Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fake-name/9ea90ec8551ee2dc3a758921c3853bec to your computer and use it in GitHub Desktop.
Save fake-name/9ea90ec8551ee2dc3a758921c3853bec to your computer and use it in GitHub Desktop.
pyfields.py
## Now with python3k support!
$ python foo.py &
[1] 21377
$ gdb -p 21377
GNU gdb (GDB) Fedora 7.7.1-17.fc20
[... gdb loading messages ...]
0x00007f9a09af46e3 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) py-bt
#4 Frame 0x22d9c70, for file foo.py, line 12, in forever ()
sleep(1)
#7 Frame 0x224f830, for file foo.py, line 14, in <module> ()
forever()
(gdb) py-print f
global 'f' = <Foo(foo=1) at remote 0x7f9a0abba830>
(gdb) py-print f.foo
'f.foo' not found
(gdb) source pyfields.py
(gdb) py-fields f.foo
global 'foo' = 1
(gdb) quit
A debugging session is active.
Inferior 1 [process 21377] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 21377
$ exit
from time import sleep
class Foo:
def __init__(self):
self.foo = 1
f = Foo()
def forever():
while f.foo == 1:
sleep(1)
forever()
class PyPrintFields(gdb.Command):
'Look up the given python variable name, and print it'
def __init__(self):
gdb.Command.__init__ (self,
"py-fields",
gdb.COMMAND_DATA,
gdb.COMPLETE_NONE)
def invoke(self, args, from_tty):
name = str(args)
frame = Frame.get_selected_python_frame()
if not frame:
print('Unable to locate python frame')
return
pyop_frame = frame.get_pyop()
if not pyop_frame:
print('Unable to read information on python frame')
return
def get_var_dict(v):
print("V: ", v)
if isinstance(v, HeapTypeObjectPtr):
return v.get_attr_dict()
elif isinstance(v, PyInstanceObjectPtr):
return v.pyop_field('in_dict')
else:
return {}
parent = None
fields = name.split('.')
for name in fields:
if parent is None:
pyop_var, scope = pyop_frame.get_var_by_name(name)
else:
for k, pyop_var in get_var_dict(parent).iteritems():
# Assuming x is a PyUnicodeObjectPtr object here.
if k.proxyval(False) == name:
break
else:
print("Can't find field %s of %s" % (name, parent))
return
parent = pyop_var
if pyop_var:
print(('%s %r = %s')
% (scope,
name,
pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
else:
print('%r not found' % name)
PyPrintFields()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment