summaryrefslogtreecommitdiffstats
path: root/Tools/gdb/libpython.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/gdb/libpython.py')
-rwxr-xr-xTools/gdb/libpython.py67
1 files changed, 48 insertions, 19 deletions
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index 32341e7..ed515c0 100755
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -56,20 +56,33 @@ if sys.version_info[0] >= 3:
long = int
# Look up the gdb.Type for some standard types:
-_type_char_ptr = gdb.lookup_type('char').pointer() # char*
-_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char*
-_type_void_ptr = gdb.lookup_type('void').pointer() # void*
-_type_unsigned_short_ptr = gdb.lookup_type('unsigned short').pointer()
-_type_unsigned_int_ptr = gdb.lookup_type('unsigned int').pointer()
+# Those need to be refreshed as types (pointer sizes) may change when
+# gdb loads different executables
-# value computed later, see PyUnicodeObjectPtr.proxy()
-_is_pep393 = None
+def _type_char_ptr():
+ return gdb.lookup_type('char').pointer() # char*
-SIZEOF_VOID_P = _type_void_ptr.sizeof
+def _type_unsigned_char_ptr():
+ return gdb.lookup_type('unsigned char').pointer() # unsigned char*
+
+
+def _type_unsigned_short_ptr():
+ return gdb.lookup_type('unsigned short').pointer()
+
+
+def _type_unsigned_int_ptr():
+ return gdb.lookup_type('unsigned int').pointer()
-Py_TPFLAGS_HEAPTYPE = (1 << 9)
+def _sizeof_void_p():
+ return gdb.lookup_type('void').pointer().sizeof
+
+
+# value computed later, see PyUnicodeObjectPtr.proxy()
+_is_pep393 = None
+
+Py_TPFLAGS_HEAPTYPE = (1 << 9)
Py_TPFLAGS_LONG_SUBCLASS = (1 << 24)
Py_TPFLAGS_LIST_SUBCLASS = (1 << 25)
Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26)
@@ -460,8 +473,8 @@ def _PyObject_VAR_SIZE(typeobj, nitems):
return ( ( typeobj.field('tp_basicsize') +
nitems * typeobj.field('tp_itemsize') +
- (SIZEOF_VOID_P - 1)
- ) & ~(SIZEOF_VOID_P - 1)
+ (_sizeof_void_p() - 1)
+ ) & ~(_sizeof_void_p() - 1)
).cast(_PyObject_VAR_SIZE._type_size_t)
_PyObject_VAR_SIZE._type_size_t = None
@@ -485,9 +498,9 @@ class HeapTypeObjectPtr(PyObjectPtr):
size = _PyObject_VAR_SIZE(typeobj, tsize)
dictoffset += size
assert dictoffset > 0
- assert dictoffset % SIZEOF_VOID_P == 0
+ assert dictoffset % _sizeof_void_p() == 0
- dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset
+ dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
dictptr = dictptr.cast(PyObjectPtrPtr)
return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
@@ -1004,7 +1017,7 @@ class PyBytesObjectPtr(PyObjectPtr):
def __str__(self):
field_ob_size = self.field('ob_size')
field_ob_sval = self.field('ob_sval')
- char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr)
+ char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
def proxyval(self, visited):
@@ -1135,11 +1148,11 @@ class PyUnicodeObjectPtr(PyObjectPtr):
field_str = self.field('data')['any']
repr_kind = int(state['kind'])
if repr_kind == 1:
- field_str = field_str.cast(_type_unsigned_char_ptr)
+ field_str = field_str.cast(_type_unsigned_char_ptr())
elif repr_kind == 2:
- field_str = field_str.cast(_type_unsigned_short_ptr)
+ field_str = field_str.cast(_type_unsigned_short_ptr())
elif repr_kind == 4:
- field_str = field_str.cast(_type_unsigned_int_ptr)
+ field_str = field_str.cast(_type_unsigned_int_ptr())
else:
# Python 3.2 and earlier
field_length = long(self.field('length'))
@@ -1514,7 +1527,11 @@ class Frame(object):
def get_selected_python_frame(cls):
'''Try to obtain the Frame for the python-related code in the selected
frame, or None'''
- frame = cls.get_selected_frame()
+ try:
+ frame = cls.get_selected_frame()
+ except gdb.error:
+ # No frame: Python didn't start yet
+ return None
while frame:
if frame.is_python_frame():
@@ -1655,6 +1672,10 @@ PyList()
def move_in_stack(move_up):
'''Move up or down the stack (for the py-up/py-down command)'''
frame = Frame.get_selected_python_frame()
+ if not frame:
+ print('Unable to locate python frame')
+ return
+
while frame:
if move_up:
iter_frame = frame.older()
@@ -1717,6 +1738,10 @@ class PyBacktraceFull(gdb.Command):
def invoke(self, args, from_tty):
frame = Frame.get_selected_python_frame()
+ if not frame:
+ print('Unable to locate python frame')
+ return
+
while frame:
if frame.is_python_frame():
frame.print_summary()
@@ -1734,8 +1759,12 @@ class PyBacktrace(gdb.Command):
def invoke(self, args, from_tty):
- sys.stdout.write('Traceback (most recent call first):\n')
frame = Frame.get_selected_python_frame()
+ if not frame:
+ print('Unable to locate python frame')
+ return
+
+ sys.stdout.write('Traceback (most recent call first):\n')
while frame:
if frame.is_python_frame():
frame.print_traceback()