@@ -362,6 +362,7 @@ def subclass_from_type(cls, t):
362362 'set' : PySetObjectPtr ,
363363 'frozenset' : PySetObjectPtr ,
364364 'builtin_function_or_method' : PyCFunctionObjectPtr ,
365+ 'method-wrapper' : wrapperobject ,
365366 }
366367 if tp_name in name_map :
367368 return name_map [tp_name ]
@@ -1330,6 +1331,39 @@ def write_repr(self, out, visited):
13301331 out .write (quote )
13311332
13321333
1334+ class wrapperobject (PyObjectPtr ):
1335+ _typename = 'wrapperobject'
1336+
1337+ def safe_name (self ):
1338+ try :
1339+ name = self .field ('descr' )['d_base' ]['name' ].string ()
1340+ return repr (name )
1341+ except (NullPyObjectPtr , RuntimeError ):
1342+ return '<unknown name>'
1343+
1344+ def safe_tp_name (self ):
1345+ try :
1346+ return self .field ('self' )['ob_type' ]['tp_name' ].string ()
1347+ except (NullPyObjectPtr , RuntimeError ):
1348+ return '<unknown tp_name>'
1349+
1350+ def safe_self_addresss (self ):
1351+ try :
1352+ address = long (self .field ('self' ))
1353+ return '%#x' % address
1354+ except (NullPyObjectPtr , RuntimeError ):
1355+ return '<failed to get self address>'
1356+
1357+ def proxyval (self , visited ):
1358+ name = self .safe_name ()
1359+ tp_name = self .safe_tp_name ()
1360+ self_address = self .safe_self_addresss ()
1361+ return ("<method-wrapper %s of %s object at %s>"
1362+ % (name , tp_name , self_address ))
1363+
1364+ def write_repr (self , out , visited ):
1365+ proxy = self .proxyval (visited )
1366+ out .write (proxy )
13331367
13341368
13351369def int_from_int (gdbval ):
@@ -1364,11 +1398,13 @@ def to_string (self):
13641398
13651399def pretty_printer_lookup (gdbval ):
13661400 type = gdbval .type .unqualified ()
1367- if type .code == gdb .TYPE_CODE_PTR :
1368- type = type .target ().unqualified ()
1369- t = str (type )
1370- if t in ("PyObject" , "PyFrameObject" , "PyUnicodeObject" ):
1371- return PyObjectPtrPrinter (gdbval )
1401+ if type .code != gdb .TYPE_CODE_PTR :
1402+ return None
1403+
1404+ type = type .target ().unqualified ()
1405+ t = str (type )
1406+ if t in ("PyObject" , "PyFrameObject" , "PyUnicodeObject" , "wrapperobject" ):
1407+ return PyObjectPtrPrinter (gdbval )
13721408
13731409"""
13741410During development, I've been manually invoking the code in this way:
@@ -1520,6 +1556,13 @@ def is_other_python_frame(self):
15201556 except RuntimeError :
15211557 return 'PyCFunction invocation (unable to read %s)' % arg_name
15221558
1559+ if caller == 'wrapper_call' :
1560+ try :
1561+ func = frame .read_var ('wp' )
1562+ return str (func )
1563+ except RuntimeError :
1564+ return '<wrapper_call invocation>'
1565+
15231566 # This frame isn't worth reporting:
15241567 return False
15251568
0 commit comments