[Python-checkins] cpython (3.5): python-gdb.py: get C types at runtime

victor.stinner python-checkins at python.org
Wed Apr 20 12:15:01 EDT 2016


https://hg.python.org/cpython/rev/e1c6f8895fd8
changeset:   101080:e1c6f8895fd8
branch:      3.5
parent:      101074:a54f6e207b22
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Wed Apr 20 18:07:21 2016 +0200
summary:
  python-gdb.py: get C types at runtime

Issue #26799: Fix python-gdb.py: don't get once C types when the Python code
is loaded, but get C types on demande. The C types can change if
python-gdb.py is loaded before the Python executable.

Patch written by Thomas Ilsche.

files:
  Misc/ACKS              |   1 +
  Misc/NEWS              |   5 +++
  Tools/gdb/libpython.py |  47 +++++++++++++++++++++--------
  3 files changed, 39 insertions(+), 14 deletions(-)


diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -648,6 +648,7 @@
 Mihai Ibanescu
 Ali Ikinci
 Aaron Iles
+Thomas Ilsche
 Lars Immisch
 Bobby Impollonia
 Naoki Inada
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -467,6 +467,11 @@
 Tools/Demos
 -----------
 
+- Issue #26799: Fix python-gdb.py: don't get once C types when the Python code
+  is loaded, but get C types on demande. The C types can change if
+  python-gdb.py is loaded before the Python executable. Patch written by Thomas
+  Ilsche.
+
 - Issue #26271: Fix the Freeze tool to properly use flags passed through
   configure. Patch by Daniel Shaulov.
 
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -56,16 +56,35 @@
     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
+
+
+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 _type_void_ptr():
+    return gdb.lookup_type('void').pointer()  # void*
+
+
+def _type_unsigned_short_ptr():
+    return gdb.lookup_type('unsigned short').pointer()
+
+
+def _type_unsigned_int_ptr():
+    return gdb.lookup_type('unsigned int').pointer()
 
 # value computed later, see PyUnicodeObjectPtr.proxy()
 _is_pep393 = None
 
-SIZEOF_VOID_P = _type_void_ptr.sizeof
+
+def _sizeof_void_p():
+    return _type_void_ptr().sizeof
 
 
 Py_TPFLAGS_HEAPTYPE = (1 << 9)
@@ -460,8 +479,8 @@
 
     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 +504,9 @@
                     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 +1023,7 @@
     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 +1154,11 @@
                     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'))

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list