Page MenuHomePhabricator
Paste P10479

py-bt-linked.py
ActivePublic

Authored by zhuyifei1999 on Feb 23 2020, 11:08 PM.
# adapted some code from https://github.com/python/cpython/blob/2.7/Tools/gdb/libpython.py
class PyBtLinked(gdb.Command):
def __init__(self):
gdb.Command.__init__ (self,
"py-bt-linked",
gdb.COMMAND_STACK,
gdb.COMPLETE_NONE)
def invoke(self, args, from_tty):
try:
print('Traceback (most recent call first):')
def p_stack(filename, lineno, funcname):
print(' File "{}", line {}, in {}'.format(
filename if filename is not None else '<possibly built-in>',
lineno, funcname))
if filename is not None:
import os
try:
cwd = os.readlink('/proc/{}/cwd'.format(gdb.selected_inferior().pid))
except IOError:
pass
else:
filename = os.path.join(cwd, filename)
try:
file = open(filename, 'rb')
except IOError:
print(' <can\'t open "{}">'.format(filename))
else:
with file:
print(' ' +
file.read().split(b'\n')[int(lineno)-1]
.decode('utf-8').strip())
def pystr(pystrptr):
assert pystrptr['ob_type']['tp_name'].string() == 'str'
pystrptr = pystrptr.cast(gdb.lookup_type('PyStringObject').pointer())
field_ob_size = int(pystrptr['ob_size'])
field_ob_sval = pystrptr['ob_sval']
return ''.join(chr(field_ob_sval[i]) for i in range(field_ob_size))
def addr2line(code, addrq):
co_lnotab = pystr(code['co_lnotab'])
lineno = int(code['co_firstlineno'])
addr = 0
for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
addr += ord(addr_incr)
if addr > addrq:
return lineno
lineno += ord(line_incr)
return lineno
filename, lineno = None, '?'
frame = None
gdbframe = gdb.newest_frame()
while not frame:
gdbframe = gdbframe.older()
regs = ['rax', 'rbx', 'rcx', 'rdx', 'rsi', 'rdi', 'rbp', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']
for reg in regs:
r = gdbframe.read_register(reg)
try:
r = r.cast(gdb.lookup_type('PyFrameObject').pointer())
if r['ob_type']['tp_name'].string() == 'frame':
frame = r
except Exception:
continue
while frame:
code = frame['f_code']
filename = pystr(code['co_filename'])
lineno = addr2line(code, int(frame['f_lasti']))
funcname = pystr(code['co_name'])
p_stack(filename, lineno, funcname)
frame = frame['f_back']
except Exception:
import traceback
traceback.print_exc()
PyBtLinked()