Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4e75ca8

Browse files
committed
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.
1 parent 8f26565 commit 4e75ca8

3 files changed

Lines changed: 39 additions & 14 deletions

File tree

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ Catalin Iacob
648648
Mihai Ibanescu
649649
Ali Ikinci
650650
Aaron Iles
651+
Thomas Ilsche
651652
Lars Immisch
652653
Bobby Impollonia
653654
Naoki Inada

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,11 @@ Windows
467467
Tools/Demos
468468
-----------
469469

470+
- Issue #26799: Fix python-gdb.py: don't get once C types when the Python code
471+
is loaded, but get C types on demande. The C types can change if
472+
python-gdb.py is loaded before the Python executable. Patch written by Thomas
473+
Ilsche.
474+
470475
- Issue #26271: Fix the Freeze tool to properly use flags passed through
471476
configure. Patch by Daniel Shaulov.
472477

Tools/gdb/libpython.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,35 @@
5656
long = int
5757

5858
# Look up the gdb.Type for some standard types:
59-
_type_char_ptr = gdb.lookup_type('char').pointer() # char*
60-
_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char*
61-
_type_void_ptr = gdb.lookup_type('void').pointer() # void*
62-
_type_unsigned_short_ptr = gdb.lookup_type('unsigned short').pointer()
63-
_type_unsigned_int_ptr = gdb.lookup_type('unsigned int').pointer()
59+
# Those need to be refreshed as types (pointer sizes) may change when
60+
# gdb loads different executables
61+
62+
63+
def _type_char_ptr():
64+
return gdb.lookup_type('char').pointer() # char*
65+
66+
67+
def _type_unsigned_char_ptr():
68+
return gdb.lookup_type('unsigned char').pointer() # unsigned char*
69+
70+
71+
def _type_void_ptr():
72+
return gdb.lookup_type('void').pointer() # void*
73+
74+
75+
def _type_unsigned_short_ptr():
76+
return gdb.lookup_type('unsigned short').pointer()
77+
78+
79+
def _type_unsigned_int_ptr():
80+
return gdb.lookup_type('unsigned int').pointer()
6481

6582
# value computed later, see PyUnicodeObjectPtr.proxy()
6683
_is_pep393 = None
6784

68-
SIZEOF_VOID_P = _type_void_ptr.sizeof
85+
86+
def _sizeof_void_p():
87+
return _type_void_ptr().sizeof
6988

7089

7190
Py_TPFLAGS_HEAPTYPE = (1 << 9)
@@ -460,8 +479,8 @@ def _PyObject_VAR_SIZE(typeobj, nitems):
460479

461480
return ( ( typeobj.field('tp_basicsize') +
462481
nitems * typeobj.field('tp_itemsize') +
463-
(SIZEOF_VOID_P - 1)
464-
) & ~(SIZEOF_VOID_P - 1)
482+
(_sizeof_void_p() - 1)
483+
) & ~(_sizeof_void_p() - 1)
465484
).cast(_PyObject_VAR_SIZE._type_size_t)
466485
_PyObject_VAR_SIZE._type_size_t = None
467486

@@ -485,9 +504,9 @@ def get_attr_dict(self):
485504
size = _PyObject_VAR_SIZE(typeobj, tsize)
486505
dictoffset += size
487506
assert dictoffset > 0
488-
assert dictoffset % SIZEOF_VOID_P == 0
507+
assert dictoffset % _sizeof_void_p() == 0
489508

490-
dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset
509+
dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
491510
PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
492511
dictptr = dictptr.cast(PyObjectPtrPtr)
493512
return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
@@ -1004,7 +1023,7 @@ class PyBytesObjectPtr(PyObjectPtr):
10041023
def __str__(self):
10051024
field_ob_size = self.field('ob_size')
10061025
field_ob_sval = self.field('ob_sval')
1007-
char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr)
1026+
char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
10081027
return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
10091028

10101029
def proxyval(self, visited):
@@ -1135,11 +1154,11 @@ def proxyval(self, visited):
11351154
field_str = self.field('data')['any']
11361155
repr_kind = int(state['kind'])
11371156
if repr_kind == 1:
1138-
field_str = field_str.cast(_type_unsigned_char_ptr)
1157+
field_str = field_str.cast(_type_unsigned_char_ptr())
11391158
elif repr_kind == 2:
1140-
field_str = field_str.cast(_type_unsigned_short_ptr)
1159+
field_str = field_str.cast(_type_unsigned_short_ptr())
11411160
elif repr_kind == 4:
1142-
field_str = field_str.cast(_type_unsigned_int_ptr)
1161+
field_str = field_str.cast(_type_unsigned_int_ptr())
11431162
else:
11441163
# Python 3.2 and earlier
11451164
field_length = long(self.field('length'))

0 commit comments

Comments
 (0)