]> granicus.if.org Git - python/commitdiff
Fix python-gdb.py: get C types on demand
authorVictor Stinner <victor.stinner@gmail.com>
Wed, 20 Apr 2016 16:23:13 +0000 (18:23 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 20 Apr 2016 16:23:13 +0000 (18:23 +0200)
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.

Misc/ACKS
Misc/NEWS
Tools/gdb/libpython.py

index 4077b5b78fbd5e2b4c4242690ceaea7234360bdb..eaee3343c84d6d3d4d609f7550596632768a4730 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -618,6 +618,7 @@ Catalin Iacob
 Mihai Ibanescu
 Ali Ikinci
 Aaron Iles
+Thomas Ilsche
 Lars Immisch
 Bobby Impollonia
 Meador Inge
index 3476b0bf4ae08d34402e09f4b1f4a544ff715271..1b486a17abed696f71f78622335b1030d6647af3 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -255,6 +255,14 @@ Build
 
 - Issue #25136: Support Apple Xcode 7's new textual SDK stub libraries.
 
+Tools/Demos
+-----------
+
+- 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.
+
 C API
 -----
 
index e713654d84c1d35e6ce3c92836c10b9a917da948..e218a31f59c177c9d41eb3f0a2e208b94edfb2fb 100755 (executable)
@@ -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)])