Python memory debugging with GDB
Yes, you can do this kind of thing:
(gdb) print PyRun_SimpleString("import traceback; traceback.print_stack()")
File "<string>", line 1, in <module>
File "/var/tmp/foo.py", line 2, in <module>
i**2
File "<string>", line 1, in <module>
$1 = 0
It should also be possible to use the pystack
command defined in the python gdbinit file, but it's not working for me. It's discussed here if you want to look into it.
Also, if you suspect memory issues, it's worth noting that you can use valgrind
with python, if you're prepared to recompile it. The procedure is described here.
How to debug Python memory fault?
You can try Low-level Python debugging with GDB. Probably there is a bug in Python interpreter or in lxml library and it is hard to find it without extra tools.
You can interrupt your script running under gdb when CPU usage goes to 100% and look at stack trace. It will probably help to understand what's going on inside script.
gdb python module read memory content
I guess inferior is what you want:
(gdb) python i = gdb.inferiors()[0]
(gdb) python m = i.read_memory(0x7fffffffe39c, 4) # an int32
(gdb) python print(m.tobytes())
b'\x01\x00\x00\x00'
Memory dump formatted like xxd from gdb
(gdb) define xxd
>dump binary memory dump.bin $arg0 $arg0+$arg1
>shell xxd dump.bin
>end
(gdb) xxd &j 10
0000000: 0000 0000 0000 0000 0000 0000 4d8c a7f7 ............M...
0000010: ff7f 0000 0000 0000 0000 0000 c8d7 ffff ................
0000020: ff7f 0000 0000 0000
Seems easy enough ;-)
You could likely write a Python script (modern GDB versions have embedded Python interpreter) to do the same, and get rid of the need to "shell out".
Update:
Here is a possible Python implementation (save this into xxd.py
):
class XXD(gdb.Command):
def __init__(self):
super(XXD, self).__init__("xxd", gdb.COMMAND_USER)
def _PrintLine(self, offset, bytes, size):
print('{:08x}: '.format(offset), end='')
todo = size
while todo >= 4:
print(''.join('{:02x}'.format(b) for b in bytes[0:4]), end='')
todo -= 4
bytes = bytes[3:]
if todo:
print(' ', end='')
# Print any remaining bytes
print(''.join('{:02x}'.format(b) for b in bytes[0:todo]), end='')
print()
return size
def invoke(self, arg, from_tty):
args = arg.split()
if len(args) != 2:
print("xxd: <addr> <count>")
return
size = int(args[1])
addr = gdb.parse_and_eval(args[0])
inferior = gdb.inferiors()[0]
bytes = inferior.read_memory(addr, size).tobytes()
offset = int(addr)
while size > 0:
n = self._PrintLine(offset, bytes, min(len(bytes), 16))
size -= n
offset += n
bytes = bytes[n:]
XXD()
Use it like so:
// Sample program x.c
char foo[] = "abcdefghijklmopqrstuvwxyz";
int main() { return 0; }
gcc -g x.c
gdb -q ./a.out
(gdb) source xxd.py
Temporary breakpoint 1, main () at x.c:3
3 int main() { return 0; }
(gdb) xxd &foo[0] 18
00404030: 61626364 64656667 6768696a 6a6b6c6d
00404040: 7273
gdb dump memory & errors?
While @scott is correct, the answer here was that I didn't account for a snapshot of the memory at the time of the process running.
I had to implement a loop to perform the a comparative analysis of the current memory allocated to the process id found in /proc//mem.
Here is a gist of the total solution.
Related Topics
How Would a Python Script Running on Linux Call a Routine in a Python Script Running Under Wine
Pyodbc:Can't Open the Driver Even If It Exists
Global Keybinding on X Using Python Gtk3
Histogram of an Image's "Black Ink Level" by Horizontal Axis
Why Is My Python App Stalled with 'System'/Kernel CPU Time
Virtualenv Uses Wrong Python, Even Though It Is First in $Path
How to Delete a File or Folder in Python
Run Python Script Only If It's Not Running
Plt.Figure.Figure.Show() Does Nothing When Not Executing Interactively
Installing Python 2.7 Without Root
How to Disable Stdout Buffer When Running Shell
Package Libffi Was Not Found in the Pkg-Config Search Path Redhat6.5
Python Multiprocessing Pool.Apply_Async with Shared Variables (Value)
Python Ctypes Not Loading Dynamic Library on MAC Os X
Detect User Logout/Shutdown in Python/Gtk Under Linux - Sigterm/Hup Not Received
A Way to "Listen" for Changes to a File System from Python on Linux