summaryrefslogtreecommitdiffstats
path: root/Tools/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/gdb')
-rwxr-xr-xTools/gdb/libpython.py23
1 files changed, 22 insertions, 1 deletions
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index 946af4b..ed25415 100755
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -77,6 +77,10 @@ def _managed_dict_offset():
else:
return -3 * _sizeof_void_p()
+def _interp_frame_has_tlbc_index():
+ interp_frame = gdb.lookup_type("_PyInterpreterFrame")
+ return any(field.name == "tlbc_index" for field in interp_frame.fields())
+
Py_TPFLAGS_INLINE_VALUES = (1 << 2)
Py_TPFLAGS_MANAGED_DICT = (1 << 4)
@@ -105,6 +109,8 @@ FRAME_INFO_OPTIMIZED_OUT = '(frame information optimized out)'
UNABLE_READ_INFO_PYTHON_FRAME = 'Unable to read information on python frame'
EVALFRAME = '_PyEval_EvalFrameDefault'
+INTERP_FRAME_HAS_TLBC_INDEX = _interp_frame_has_tlbc_index()
+
class NullPyObjectPtr(RuntimeError):
pass
@@ -693,6 +699,16 @@ def parse_location_table(firstlineno, linetable):
yield addr, end_addr, line
addr = end_addr
+
+class PyCodeArrayPtr:
+ def __init__(self, gdbval):
+ self._gdbval = gdbval
+
+ def get_entry(self, index):
+ assert (index >= 0) and (index < self._gdbval["size"])
+ return self._gdbval["entries"][index]
+
+
class PyCodeObjectPtr(PyObjectPtr):
"""
Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
@@ -1085,7 +1101,12 @@ class PyFramePtr:
def _f_lasti(self):
codeunit_p = gdb.lookup_type("_Py_CODEUNIT").pointer()
instr_ptr = self._gdbval["instr_ptr"]
- first_instr = self._f_code().field("co_code_adaptive").cast(codeunit_p)
+ if INTERP_FRAME_HAS_TLBC_INDEX:
+ tlbc_index = self._gdbval["tlbc_index"]
+ code_arr = PyCodeArrayPtr(self._f_code().field("co_tlbc"))
+ first_instr = code_arr.get_entry(tlbc_index).cast(codeunit_p)
+ else:
+ first_instr = self._f_code().field("co_code_adaptive").cast(codeunit_p)
return int(instr_ptr - first_instr)
def is_shim(self):