summaryrefslogtreecommitdiffstats
path: root/Tools/gdb/libpython.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-04-20 16:23:13 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-04-20 16:23:13 (GMT)
commitf6f617c5f77440f681857c9b116b929c1044b26a (patch)
treeb848e4aa728690e065cdf30c903e609234c51a75 /Tools/gdb/libpython.py
parent5b48fa9fa4f0848c26ba6a8d7bdaf1c4f555527c (diff)
downloadcpython-f6f617c5f77440f681857c9b116b929c1044b26a.zip
cpython-f6f617c5f77440f681857c9b116b929c1044b26a.tar.gz
cpython-f6f617c5f77440f681857c9b116b929c1044b26a.tar.bz2
Fix python-gdb.py: get C types on demand
Issue #26799: Fix python-gdb.py: don't get C types once when the Python code is loaded, but get C types on demand. The C types can change if python-gdb.py is loaded before the Python executable. Patch written by Thomas Ilsche.
Diffstat (limited to 'Tools/gdb/libpython.py')
-rwxr-xr-xTools/gdb/libpython.py26
1 files changed, 17 insertions, 9 deletions
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index e713654..e218a31 100755
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -55,11 +55,19 @@ 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*
+# Those need to be refreshed as types (pointer sizes) may change when
+# gdb loads different executables
-SIZEOF_VOID_P = _type_void_ptr.sizeof
+def _type_char_ptr():
+ return gdb.lookup_type('char').pointer() # char*
+
+
+def _type_unsigned_char_ptr():
+ return gdb.lookup_type('unsigned char').pointer() # unsigned char*
+
+
+def _sizeof_void_p():
+ return gdb.lookup_type('void').pointer().sizeof
Py_TPFLAGS_HEAPTYPE = (1 << 9)
@@ -439,8 +447,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
@@ -464,9 +472,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())
@@ -1014,7 +1022,7 @@ class PyStringObjectPtr(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())
# When gdb is linked with a Python 3 interpreter, this is really
# a latin-1 mojibake decoding of the original string...
return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])