@@ -362,6 +362,7 @@ def subclass_from_type(cls, t):
362
362
'set' : PySetObjectPtr ,
363
363
'frozenset' : PySetObjectPtr ,
364
364
'builtin_function_or_method' : PyCFunctionObjectPtr ,
365
+ 'method-wrapper' : wrapperobject ,
365
366
}
366
367
if tp_name in name_map :
367
368
return name_map [tp_name ]
@@ -1330,6 +1331,39 @@ def write_repr(self, out, visited):
1330
1331
out .write (quote )
1331
1332
1332
1333
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 )
1333
1367
1334
1368
1335
1369
def int_from_int (gdbval ):
@@ -1364,11 +1398,13 @@ def to_string (self):
1364
1398
1365
1399
def pretty_printer_lookup (gdbval ):
1366
1400
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 )
1372
1408
1373
1409
"""
1374
1410
During development, I've been manually invoking the code in this way:
@@ -1520,6 +1556,13 @@ def is_other_python_frame(self):
1520
1556
except RuntimeError :
1521
1557
return 'PyCFunction invocation (unable to read %s)' % arg_name
1522
1558
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
+
1523
1566
# This frame isn't worth reporting:
1524
1567
return False
1525
1568
0 commit comments