Red Hat Bugzilla – Bug 639392
Generating python backtrace with "py-bt" fails with a traceback
Last modified: 2016-05-31 21:47:17 EDT
Description of problem: Using python gdb command "py-bt" to generate backtrace results in a python traceback. This is x86_64-only, works fine on all other architectures. # rpm -q python gdb python-2.6.5-3.el6.x86_64 gdb-7.1-29.el6.x86_64 # cat foo.py class Foo: def bar(self): from ctypes import string_at string_at(0xDEADBEEF) # this code will cause Python to segfault f = Foo() # Let's assign some data of various kinds to the instance: f.someattr = 42 f.someotherattr = {'one':1, 'two':2L, 'three':[(), (None,), (None, None)]} # Now let's trigger the segfault f.bar() # gdb -q --args python foo.py Reading symbols from /usr/bin/python...Reading symbols from /usr/lib/debug/usr/bin/python2.6.debug...done. done. (gdb) r Starting program: /usr/bin/python foo.py [Thread debugging using libthread_db enabled] Program received signal SIGSEGV, Segmentation fault. __strlen_sse2 () at ../sysdeps/x86_64/strlen.S:31 31 pcmpeqb (%rdi), %xmm2 (gdb) py-bt #10 (unable to read python frame information) #14 (unable to read python frame information) Traceback (most recent call last): File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 1326, in invoke frame.print_summary() File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 1181, in print_summary pyop = self.get_pyop() File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 1154, in get_pyop return PyFrameObjectPtr.from_pyobject_ptr(f) File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 349, in from_pyobject_ptr return cls(gdbval) TypeError: __init__() takes exactly 3 arguments (2 given) Error occurred in Python command.
The code in question is the error-handling pass here (still present in upstream code): try: p = PyObjectPtr(gdbval) cls = cls.subclass_from_type(p.type()) return cls(gdbval, cast_to=cls.get_gdb_type()) except RuntimeError: # Handle any kind of error e.g. NULL ptrs by simply using the base # class pass return cls(gdbval) I've seen this backtrace from time to time; haven't yet been able to reproduce it at will. It should be possible to fix this by replacing the above with something like: p = PyObjectPtr(gdbval) try: cls = cls.subclass_from_type(p.type()) return cls(gdbval, cast_to=cls.get_gdb_type()) except RuntimeError: # Handle any kind of error e.g. NULL ptrs by simply using the base # class pass return p though I'm not yet sure if that's the correct fix.
Correction: the reproducer in comment #0 does reliably reproduce this for me (on x86_64) Trying the approach in comment #1 doesn't work; I get: Traceback (most recent call last): File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 1325, in invoke frame.print_summary() File "/usr/lib/debug/usr/lib64/libpython2.6.so.1.0.debug-gdb.py", line 1183, in print_summary sys.stdout.write(pyop.current_line()) AttributeError: 'PyObjectPtr' object has no attribute 'current_line' Error occurred in Python command: 'PyObjectPtr' object has no attribute 'current_line'
Technical note added. If any revisions are required, please edit the "Technical Notes" field accordingly. All revisions will be proofread by the Engineering Content Services team. New Contents: On AMD64 and Intel 64 architectures, running gdb (configured using "--with-python") on python applications to generate backtraces caused a traceback error. python-gdb.py, the python module that deals with the case of debugging a python process, was updated to prevent this.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHSA-2011-0554.html