I screwed up using git ("git checkout --" on the wrong file) and managed to delete the code I had just written... but it was still running in a process in a docker container. Here's how I got it back, using https://pypi.python.org/pypi/pyrasite/ and https://pypi.python.org/pypi/uncompyle6
apt-get update && apt-get install gdb
pip install pyrasite
pip install uncompyle6
ps aux | grep python
pyrasite-shell <PID>
>>> from my_package import my_module
>>> dir(my_module)
['MyClass', 'my_function']
>>> import uncompyle6
>>> import sys
>>> uncompyle6.main.uncompyle(
2.7, my_module.my_function.func_code, sys.stdout
)
# uncompyle6 version 2.9.10
# Python bytecode 2.7
# Decompiled from: Python 2.7.12 (default, Nov 19 2016, 06:48:10)
# [GCC 5.4.0 20160609]
# Embedded file name: /srv/my_package/my_module.py
function_body = "appears here"
>>> uncompyle6.main.uncompyle(
2.7, my_module.MyClass.my_method.im_func.func_code, sys.stdout
)
# uncompyle6 version 2.9.10
# Python bytecode 2.7
# Decompiled from: Python 2.7.12 (default, Nov 19 2016, 06:48:10)
# [GCC 5.4.0 20160609]
# Embedded file name: /srv/my_package/my_module.py
class_method_body = "appears here"
FYI, this feels incredibly complicated. Here's a much simpler method that universally applies to any process and will probably recover the original source, or very close to it - for example I used this approach to recover some text from a textbox in Chrome when an undo operation went awry recently. Using Python as an example:
(Leave that running, then...)
Left in some of the binary asplosion for fun; this is a Unicode world now after all, it shouldn't cause any issues. As you can see, some of the data (a ridiculously small amount here) is mangled, but I see at least three intact copies of my original text. YMMV depending on what
malloc
implementation your app is using and how much fragmentation happened.Here's one to file away if you frequently use Linux:
configure enough swapspace on your system, then in an absolute emergency open a terminal and run
sync
thenecho disk > /sys/power/state
orpm-hibernate
to trigger system hibernation. Of course, this process requires a full copy of memory to be written to the disk... :) reboot your system off a flash drive for best results analysing the disk. WARNING: It feels horribly unintuitive but you mustsync
your disk before hibernating unless you know you'll be able to successfully resume off of the hibernated memory image, because of course hibernating means that whatever the filesystem was doing is immediately abandoned in-flight, with the idea that it will be finished when the system wakes back up! If you never resume, that in-memory filesystem data never makes it to disk. Ideally you'd copy the memory image somewhere then resume from the hibernated image; it might be worth figuring out how to do that on your system.And of course this is all because Linux doesn't provide arbitrary access to memory. Kinda crazy that it's not generally possible, but it's understandable.