mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
GDB: format output for class entries and class constants (#15955)
For `zend_string` pointers in class entries, show the string contents (if not `NULL`). For class constants, the `ce` (class entry pointer) field is shown with the name of the class, and the `doc_comment` field is shown with the string contents if possible.
This commit is contained in:
parent
b675db4c56
commit
e34eebb854
2 changed files with 104 additions and 0 deletions
|
@ -737,6 +737,12 @@ asm(
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
".ascii \"pp_set.add_printer('zend_string', '^_zend_string$', ZendStringPrettyPrinter)\\n\"\n"
|
".ascii \"pp_set.add_printer('zend_string', '^_zend_string$', ZendStringPrettyPrinter)\\n\"\n"
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \"def zendStringPointerPrinter(ptr):\\n\"\n"
|
||||||
|
".ascii \" \\\"Given a pointer to a zend_string, show the contents (if non-NULL)\\\"\\n\"\n"
|
||||||
|
".ascii \" if int(ptr) == 0:\\n\"\n"
|
||||||
|
".ascii \" return '0x0'\\n\"\n"
|
||||||
|
".ascii \" return ZendStringPrettyPrinter(ptr.dereference()).to_string()\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
".ascii \"class ZendTypePrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
|
".ascii \"class ZendTypePrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
|
||||||
".ascii \" \\\"Print a zend_type\\\"\\n\"\n"
|
".ascii \" \\\"Print a zend_type\\\"\\n\"\n"
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
|
@ -959,6 +965,52 @@ asm(
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
".ascii \"pp_set.add_printer('zval', '^_zval_struct$', ZvalPrettyPrinter)\\n\"\n"
|
".ascii \"pp_set.add_printer('zval', '^_zval_struct$', ZvalPrettyPrinter)\\n\"\n"
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \"class ZendClassEntryPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
|
||||||
|
".ascii \" \\\"Print a zend_class_entry\\\"\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" # String pointers, show the string contents if possible\\n\"\n"
|
||||||
|
".ascii \" STRING_FIELDS = [ 'name', 'doc_comment' ]\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" def __init__(self, val):\\n\"\n"
|
||||||
|
".ascii \" self.val = val\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" def to_string(self):\\n\"\n"
|
||||||
|
".ascii \" return zendStringPointerPrinter(self.val['name'])\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" def children(self):\\n\"\n"
|
||||||
|
".ascii \" for field in self.val.type.fields():\\n\"\n"
|
||||||
|
".ascii \" if field.name is not None:\\n\"\n"
|
||||||
|
".ascii \" if field.name in self.STRING_FIELDS:\\n\"\n"
|
||||||
|
".ascii \" yield (field.name, zendStringPointerPrinter(self.val[field.name]))\\n\"\n"
|
||||||
|
".ascii \" else:\\n\"\n"
|
||||||
|
".ascii \" yield (field.name, self.val[field.name])\\n\"\n"
|
||||||
|
".ascii \" else:\\n\"\n"
|
||||||
|
".ascii \" # Don't break on the union fields. Unfortunately, pretty\\n\"\n"
|
||||||
|
".ascii \" # printers done in python cannot match the default formatting of\\n\"\n"
|
||||||
|
".ascii \" # C anonymous fields, which omit the name entirely, see\\n\"\n"
|
||||||
|
".ascii \" # binutils-gdb/gdb/cp-valprint.c#248 (as of commit\\n\"\n"
|
||||||
|
".ascii \" # b6532accdd8e24329cc69bb58bc2883796008776)\\n\"\n"
|
||||||
|
".ascii \" yield ('<anonymous>', self.val[field])\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \"pp_set.add_printer('zend_class_entry', '^_zend_class_entry$', ZendClassEntryPrettyPrinter)\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \"class ZendClassConstantPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
|
||||||
|
".ascii \" \\\"Print a zend_class_constant\\\"\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" def __init__(self, val):\\n\"\n"
|
||||||
|
".ascii \" self.val = val\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \" def children(self):\\n\"\n"
|
||||||
|
".ascii \" for field in self.val.type.fields():\\n\"\n"
|
||||||
|
".ascii \" if field.name == 'doc_comment':\\n\"\n"
|
||||||
|
".ascii \" yield ('doc_comment', zendStringPointerPrinter(self.val['doc_comment']))\\n\"\n"
|
||||||
|
".ascii \" elif field.name == 'ce':\\n\"\n"
|
||||||
|
".ascii \" yield ('ce', zendStringPointerPrinter(self.val['ce']['name']))\\n\"\n"
|
||||||
|
".ascii \" else:\\n\"\n"
|
||||||
|
".ascii \" yield (field.name, self.val[field.name])\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
|
".ascii \"pp_set.add_printer('zend_class_constant', '^_zend_class_constant$', ZendClassConstantPrettyPrinter)\\n\"\n"
|
||||||
|
".ascii \"\\n\"\n"
|
||||||
".ascii \"type_bit_to_name = None\\n\"\n"
|
".ascii \"type_bit_to_name = None\\n\"\n"
|
||||||
".ascii \"type_name_to_bit = None\\n\"\n"
|
".ascii \"type_name_to_bit = None\\n\"\n"
|
||||||
".ascii \"\\n\"\n"
|
".ascii \"\\n\"\n"
|
||||||
|
|
|
@ -67,6 +67,12 @@ class ZendStringPrettyPrinter(gdb.printing.PrettyPrinter):
|
||||||
|
|
||||||
pp_set.add_printer('zend_string', '^_zend_string$', ZendStringPrettyPrinter)
|
pp_set.add_printer('zend_string', '^_zend_string$', ZendStringPrettyPrinter)
|
||||||
|
|
||||||
|
def zendStringPointerPrinter(ptr):
|
||||||
|
"Given a pointer to a zend_string, show the contents (if non-NULL)"
|
||||||
|
if int(ptr) == 0:
|
||||||
|
return '0x0'
|
||||||
|
return ZendStringPrettyPrinter(ptr.dereference()).to_string()
|
||||||
|
|
||||||
class ZendTypePrettyPrinter(gdb.printing.PrettyPrinter):
|
class ZendTypePrettyPrinter(gdb.printing.PrettyPrinter):
|
||||||
"Print a zend_type"
|
"Print a zend_type"
|
||||||
|
|
||||||
|
@ -289,6 +295,52 @@ class ZvalPrettyPrinter(gdb.printing.PrettyPrinter):
|
||||||
|
|
||||||
pp_set.add_printer('zval', '^_zval_struct$', ZvalPrettyPrinter)
|
pp_set.add_printer('zval', '^_zval_struct$', ZvalPrettyPrinter)
|
||||||
|
|
||||||
|
class ZendClassEntryPrettyPrinter(gdb.printing.PrettyPrinter):
|
||||||
|
"Print a zend_class_entry"
|
||||||
|
|
||||||
|
# String pointers, show the string contents if possible
|
||||||
|
STRING_FIELDS = [ 'name', 'doc_comment' ]
|
||||||
|
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return zendStringPointerPrinter(self.val['name'])
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
for field in self.val.type.fields():
|
||||||
|
if field.name is not None:
|
||||||
|
if field.name in self.STRING_FIELDS:
|
||||||
|
yield (field.name, zendStringPointerPrinter(self.val[field.name]))
|
||||||
|
else:
|
||||||
|
yield (field.name, self.val[field.name])
|
||||||
|
else:
|
||||||
|
# Don't break on the union fields. Unfortunately, pretty
|
||||||
|
# printers done in python cannot match the default formatting of
|
||||||
|
# C anonymous fields, which omit the name entirely, see
|
||||||
|
# binutils-gdb/gdb/cp-valprint.c#248 (as of commit
|
||||||
|
# b6532accdd8e24329cc69bb58bc2883796008776)
|
||||||
|
yield ('<anonymous>', self.val[field])
|
||||||
|
|
||||||
|
pp_set.add_printer('zend_class_entry', '^_zend_class_entry$', ZendClassEntryPrettyPrinter)
|
||||||
|
|
||||||
|
class ZendClassConstantPrettyPrinter(gdb.printing.PrettyPrinter):
|
||||||
|
"Print a zend_class_constant"
|
||||||
|
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
for field in self.val.type.fields():
|
||||||
|
if field.name == 'doc_comment':
|
||||||
|
yield ('doc_comment', zendStringPointerPrinter(self.val['doc_comment']))
|
||||||
|
elif field.name == 'ce':
|
||||||
|
yield ('ce', zendStringPointerPrinter(self.val['ce']['name']))
|
||||||
|
else:
|
||||||
|
yield (field.name, self.val[field.name])
|
||||||
|
|
||||||
|
pp_set.add_printer('zend_class_constant', '^_zend_class_constant$', ZendClassConstantPrettyPrinter)
|
||||||
|
|
||||||
type_bit_to_name = None
|
type_bit_to_name = None
|
||||||
type_name_to_bit = None
|
type_name_to_bit = None
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue