blob: 7c8874a7acea2c02d302a700978ddb89c6096261 [file] [log] [blame]
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001#!/usr/bin/python
2'''
3From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb
4to be extended with Python code e.g. for library-specific data visualizations,
5such as for the C++ STL types. Documentation on this API can be seen at:
6http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
7
8
9This python module deals with the case when the process being debugged (the
10"inferior process" in gdb parlance) is itself python, or more specifically,
11linked against libpython. In this situation, almost every item of data is a
12(PyObject*), and having the debugger merely print their addresses is not very
13enlightening.
14
15This module embeds knowledge about the implementation details of libpython so
16that we can emit useful visualizations e.g. a string, a list, a dict, a frame
17giving file/line information and the state of local variables
18
19In particular, given a gdb.Value corresponding to a PyObject* in the inferior
20process, we can generate a "proxy value" within the gdb process. For example,
21given a PyObject* in the inferior process that is in fact a PyListObject*
Victor Stinner67df3a42010-04-21 13:53:05 +000022holding three PyObject* that turn out to be PyBytesObject* instances, we can
Martin v. Löwis5ae68102010-04-21 22:38:42 +000023generate a proxy value within the gdb process that is a list of bytes
24instances:
25 [b"foo", b"bar", b"baz"]
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000026
27Doing so can be expensive for complicated graphs of objects, and could take
28some time, so we also have a "write_repr" method that writes a representation
29of the data to a file-like object. This allows us to stop the traversal by
30having the file-like object raise an exception if it gets too much data.
31
32With both "proxyval" and "write_repr" we keep track of the set of all addresses
33visited so far in the traversal, to avoid infinite recursion due to cycles in
34the graph of object references.
35
36We try to defer gdb.lookup_type() invocations for python types until as late as
37possible: for a dynamically linked python binary, when the process starts in
38the debugger, the libpython.so hasn't been dynamically loaded yet, so none of
39the type names are known to the debugger
40
41The module also extends gdb with some python-specific commands.
42'''
Antoine Pitroue50240c2013-11-23 17:40:36 +010043
44# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax
45# compatible (2.6+ and 3.0+). See #19308.
46
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)a68c1bc2016-09-08 13:47:41 -070047from __future__ import print_function
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000048import gdb
Antoine Pitroue50240c2013-11-23 17:40:36 +010049import os
Victor Stinner150016f2010-05-19 23:04:56 +000050import locale
Georg Brandlb639c142010-07-14 08:54:40 +000051import sys
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000052
Antoine Pitroue50240c2013-11-23 17:40:36 +010053if sys.version_info[0] >= 3:
54 unichr = chr
55 xrange = range
56 long = int
57
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000058# Look up the gdb.Type for some standard types:
Victor Stinner4e75ca82016-04-20 18:07:21 +020059# Those need to be refreshed as types (pointer sizes) may change when
60# gdb loads different executables
61
Victor Stinner4e75ca82016-04-20 18:07:21 +020062def _type_char_ptr():
63 return gdb.lookup_type('char').pointer() # char*
64
65
66def _type_unsigned_char_ptr():
67 return gdb.lookup_type('unsigned char').pointer() # unsigned char*
68
69
Victor Stinner4e75ca82016-04-20 18:07:21 +020070def _type_unsigned_short_ptr():
71 return gdb.lookup_type('unsigned short').pointer()
72
73
74def _type_unsigned_int_ptr():
75 return gdb.lookup_type('unsigned int').pointer()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000076
Victor Stinner19620c52016-04-20 18:26:12 +020077
78def _sizeof_void_p():
79 return gdb.lookup_type('void').pointer().sizeof
80
81
Victor Stinner0c4fbff2011-12-08 00:08:22 +010082# value computed later, see PyUnicodeObjectPtr.proxy()
83_is_pep393 = None
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020084
Antoine Pitroue50240c2013-11-23 17:40:36 +010085Py_TPFLAGS_HEAPTYPE = (1 << 9)
Antoine Pitroue50240c2013-11-23 17:40:36 +010086Py_TPFLAGS_LONG_SUBCLASS = (1 << 24)
87Py_TPFLAGS_LIST_SUBCLASS = (1 << 25)
88Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26)
89Py_TPFLAGS_BYTES_SUBCLASS = (1 << 27)
90Py_TPFLAGS_UNICODE_SUBCLASS = (1 << 28)
91Py_TPFLAGS_DICT_SUBCLASS = (1 << 29)
92Py_TPFLAGS_BASE_EXC_SUBCLASS = (1 << 30)
93Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +000094
95
96MAX_OUTPUT_LEN=1024
97
Martin v. Löwis5ae68102010-04-21 22:38:42 +000098hexdigits = "0123456789abcdef"
99
Victor Stinner150016f2010-05-19 23:04:56 +0000100ENCODING = locale.getpreferredencoding()
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000101
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000102class NullPyObjectPtr(RuntimeError):
103 pass
104
105
106def safety_limit(val):
Martin Panter7462b6492015-11-02 03:37:02 +0000107 # Given an integer value from the process being debugged, limit it to some
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000108 # safety threshold so that arbitrary breakage within said process doesn't
109 # break the gdb process too much (e.g. sizes of iterations, sizes of lists)
110 return min(val, 1000)
111
112
113def safe_range(val):
114 # As per range, but don't trust the value too much: cap it to a safety
115 # threshold in case the data was corrupted
Antoine Pitroue50240c2013-11-23 17:40:36 +0100116 return xrange(safety_limit(int(val)))
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000117
Antoine Pitroue50240c2013-11-23 17:40:36 +0100118if sys.version_info[0] >= 3:
119 def write_unicode(file, text):
120 file.write(text)
121else:
122 def write_unicode(file, text):
123 # Write a byte or unicode string to file. Unicode strings are encoded to
124 # ENCODING encoding with 'backslashreplace' error handler to avoid
125 # UnicodeEncodeError.
126 if isinstance(text, unicode):
127 text = text.encode(ENCODING, 'backslashreplace')
128 file.write(text)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000129
Antoine Pitroue50240c2013-11-23 17:40:36 +0100130try:
131 os_fsencode = os.fsencode
Antoine Pitrou23828f62013-11-23 18:20:42 +0100132except AttributeError:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100133 def os_fsencode(filename):
134 if not isinstance(filename, unicode):
135 return filename
136 encoding = sys.getfilesystemencoding()
137 if encoding == 'mbcs':
138 # mbcs doesn't support surrogateescape
139 return filename.encode(encoding)
140 encoded = []
141 for char in filename:
142 # surrogateescape error handler
143 if 0xDC80 <= ord(char) <= 0xDCFF:
144 byte = chr(ord(char) - 0xDC00)
145 else:
146 byte = char.encode(encoding)
147 encoded.append(byte)
148 return ''.join(encoded)
Victor Stinner6ffbee72010-10-17 19:35:30 +0000149
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000150class StringTruncated(RuntimeError):
151 pass
152
153class TruncatedStringIO(object):
Serhiy Storchaka50254c52013-08-29 11:35:43 +0300154 '''Similar to io.StringIO, but can truncate the output by raising a
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000155 StringTruncated exception'''
156 def __init__(self, maxlen=None):
157 self._val = ''
158 self.maxlen = maxlen
159
160 def write(self, data):
161 if self.maxlen:
162 if len(data) + len(self._val) > self.maxlen:
163 # Truncation:
164 self._val += data[0:self.maxlen - len(self._val)]
165 raise StringTruncated()
166
167 self._val += data
168
169 def getvalue(self):
170 return self._val
171
172class PyObjectPtr(object):
173 """
Martin Panter7462b6492015-11-02 03:37:02 +0000174 Class wrapping a gdb.Value that's either a (PyObject*) within the
Victor Stinner67df3a42010-04-21 13:53:05 +0000175 inferior process, or some subclass pointer e.g. (PyBytesObject*)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000176
177 There will be a subclass for every refined PyObject type that we care
178 about.
179
180 Note that at every stage the underlying pointer could be NULL, point
181 to corrupt data, etc; this is the debugger, after all.
182 """
183 _typename = 'PyObject'
184
185 def __init__(self, gdbval, cast_to=None):
186 if cast_to:
187 self._gdbval = gdbval.cast(cast_to)
188 else:
189 self._gdbval = gdbval
190
191 def field(self, name):
192 '''
193 Get the gdb.Value for the given field within the PyObject, coping with
194 some python 2 versus python 3 differences.
195
196 Various libpython types are defined using the "PyObject_HEAD" and
197 "PyObject_VAR_HEAD" macros.
198
199 In Python 2, this these are defined so that "ob_type" and (for a var
200 object) "ob_size" are fields of the type in question.
201
202 In Python 3, this is defined as an embedded PyVarObject type thus:
203 PyVarObject ob_base;
204 so that the "ob_size" field is located insize the "ob_base" field, and
205 the "ob_type" is most easily accessed by casting back to a (PyObject*).
206 '''
207 if self.is_null():
208 raise NullPyObjectPtr(self)
209
210 if name == 'ob_type':
211 pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type())
212 return pyo_ptr.dereference()[name]
213
214 if name == 'ob_size':
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000215 pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type())
216 return pyo_ptr.dereference()[name]
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000217
218 # General case: look it up inside the object:
219 return self._gdbval.dereference()[name]
220
221 def pyop_field(self, name):
222 '''
223 Get a PyObjectPtr for the given PyObject* field within this PyObject,
224 coping with some python 2 versus python 3 differences.
225 '''
226 return PyObjectPtr.from_pyobject_ptr(self.field(name))
227
228 def write_field_repr(self, name, out, visited):
229 '''
230 Extract the PyObject* field named "name", and write its representation
231 to file-like object "out"
232 '''
233 field_obj = self.pyop_field(name)
234 field_obj.write_repr(out, visited)
235
236 def get_truncated_repr(self, maxlen):
237 '''
238 Get a repr-like string for the data, but truncate it at "maxlen" bytes
239 (ending the object graph traversal as soon as you do)
240 '''
241 out = TruncatedStringIO(maxlen)
242 try:
243 self.write_repr(out, set())
244 except StringTruncated:
245 # Truncation occurred:
246 return out.getvalue() + '...(truncated)'
247
248 # No truncation occurred:
249 return out.getvalue()
250
251 def type(self):
252 return PyTypeObjectPtr(self.field('ob_type'))
253
254 def is_null(self):
255 return 0 == long(self._gdbval)
256
257 def is_optimized_out(self):
258 '''
259 Is the value of the underlying PyObject* visible to the debugger?
260
261 This can vary with the precise version of the compiler used to build
262 Python, and the precise version of gdb.
263
264 See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
265 PyEval_EvalFrameEx's "f"
266 '''
267 return self._gdbval.is_optimized_out
268
269 def safe_tp_name(self):
270 try:
271 return self.type().field('tp_name').string()
272 except NullPyObjectPtr:
273 # NULL tp_name?
274 return 'unknown'
275 except RuntimeError:
276 # Can't even read the object at all?
277 return 'unknown'
278
279 def proxyval(self, visited):
280 '''
281 Scrape a value from the inferior process, and try to represent it
282 within the gdb process, whilst (hopefully) avoiding crashes when
283 the remote data is corrupt.
284
285 Derived classes will override this.
286
287 For example, a PyIntObject* with ob_ival 42 in the inferior process
288 should result in an int(42) in this process.
289
290 visited: a set of all gdb.Value pyobject pointers already visited
291 whilst generating this value (to guard against infinite recursion when
292 visiting object graphs with loops). Analogous to Py_ReprEnter and
293 Py_ReprLeave
294 '''
295
296 class FakeRepr(object):
297 """
298 Class representing a non-descript PyObject* value in the inferior
299 process for when we don't have a custom scraper, intended to have
300 a sane repr().
301 """
302
303 def __init__(self, tp_name, address):
304 self.tp_name = tp_name
305 self.address = address
306
307 def __repr__(self):
308 # For the NULL pointer, we have no way of knowing a type, so
309 # special-case it as per
310 # http://bugs.python.org/issue8032#msg100882
311 if self.address == 0:
312 return '0x0'
313 return '<%s at remote 0x%x>' % (self.tp_name, self.address)
314
315 return FakeRepr(self.safe_tp_name(),
316 long(self._gdbval))
317
318 def write_repr(self, out, visited):
319 '''
320 Write a string representation of the value scraped from the inferior
321 process to "out", a file-like object.
322 '''
323 # Default implementation: generate a proxy value and write its repr
324 # However, this could involve a lot of work for complicated objects,
325 # so for derived classes we specialize this
326 return out.write(repr(self.proxyval(visited)))
327
328 @classmethod
329 def subclass_from_type(cls, t):
330 '''
331 Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
332 (PyTypeObject*), determine the corresponding subclass of PyObjectPtr
333 to use
334
335 Ideally, we would look up the symbols for the global types, but that
336 isn't working yet:
337 (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
338 Traceback (most recent call last):
339 File "<string>", line 1, in <module>
340 NotImplementedError: Symbol type not yet supported in Python scripts.
341 Error while executing Python code.
342
343 For now, we use tp_flags, after doing some string comparisons on the
344 tp_name for some special-cases that don't seem to be visible through
345 flags
346 '''
347 try:
348 tp_name = t.field('tp_name').string()
349 tp_flags = int(t.field('tp_flags'))
350 except RuntimeError:
351 # Handle any kind of error e.g. NULL ptrs by simply using the base
352 # class
353 return cls
354
Antoine Pitroue50240c2013-11-23 17:40:36 +0100355 #print('tp_flags = 0x%08x' % tp_flags)
356 #print('tp_name = %r' % tp_name)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000357
358 name_map = {'bool': PyBoolObjectPtr,
359 'classobj': PyClassObjectPtr,
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000360 'NoneType': PyNoneStructPtr,
361 'frame': PyFrameObjectPtr,
362 'set' : PySetObjectPtr,
363 'frozenset' : PySetObjectPtr,
364 'builtin_function_or_method' : PyCFunctionObjectPtr,
Victor Stinner61108332017-02-01 16:29:54 +0100365 'method-wrapper': wrapperobject,
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000366 }
367 if tp_name in name_map:
368 return name_map[tp_name]
369
370 if tp_flags & Py_TPFLAGS_HEAPTYPE:
371 return HeapTypeObjectPtr
372
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000373 if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
374 return PyLongObjectPtr
375 if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
376 return PyListObjectPtr
377 if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
378 return PyTupleObjectPtr
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000379 if tp_flags & Py_TPFLAGS_BYTES_SUBCLASS:
Victor Stinner67df3a42010-04-21 13:53:05 +0000380 return PyBytesObjectPtr
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000381 if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
382 return PyUnicodeObjectPtr
383 if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
384 return PyDictObjectPtr
385 if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
386 return PyBaseExceptionObjectPtr
387 #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
388 # return PyTypeObjectPtr
389
390 # Use the base class:
391 return cls
392
393 @classmethod
394 def from_pyobject_ptr(cls, gdbval):
395 '''
396 Try to locate the appropriate derived class dynamically, and cast
397 the pointer accordingly.
398 '''
399 try:
400 p = PyObjectPtr(gdbval)
401 cls = cls.subclass_from_type(p.type())
402 return cls(gdbval, cast_to=cls.get_gdb_type())
403 except RuntimeError:
404 # Handle any kind of error e.g. NULL ptrs by simply using the base
405 # class
406 pass
407 return cls(gdbval)
408
409 @classmethod
410 def get_gdb_type(cls):
411 return gdb.lookup_type(cls._typename).pointer()
412
413 def as_address(self):
414 return long(self._gdbval)
415
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000416class PyVarObjectPtr(PyObjectPtr):
417 _typename = 'PyVarObject'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000418
419class ProxyAlreadyVisited(object):
420 '''
421 Placeholder proxy to use when protecting against infinite recursion due to
422 loops in the object graph.
423
424 Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave
425 '''
426 def __init__(self, rep):
427 self._rep = rep
428
429 def __repr__(self):
430 return self._rep
431
432
433def _write_instance_repr(out, visited, name, pyop_attrdict, address):
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100434 '''Shared code for use by all classes:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000435 write a representation to file-like object "out"'''
436 out.write('<')
437 out.write(name)
438
439 # Write dictionary of instance attributes:
440 if isinstance(pyop_attrdict, PyDictObjectPtr):
441 out.write('(')
442 first = True
443 for pyop_arg, pyop_val in pyop_attrdict.iteritems():
444 if not first:
445 out.write(', ')
446 first = False
447 out.write(pyop_arg.proxyval(visited))
448 out.write('=')
449 pyop_val.write_repr(out, visited)
450 out.write(')')
451 out.write(' at remote 0x%x>' % address)
452
453
454class InstanceProxy(object):
455
456 def __init__(self, cl_name, attrdict, address):
457 self.cl_name = cl_name
458 self.attrdict = attrdict
459 self.address = address
460
461 def __repr__(self):
462 if isinstance(self.attrdict, dict):
463 kwargs = ', '.join(["%s=%r" % (arg, val)
464 for arg, val in self.attrdict.iteritems()])
465 return '<%s(%s) at remote 0x%x>' % (self.cl_name,
466 kwargs, self.address)
467 else:
468 return '<%s at remote 0x%x>' % (self.cl_name,
469 self.address)
470
471def _PyObject_VAR_SIZE(typeobj, nitems):
Victor Stinnerd2084162011-12-19 13:42:24 +0100472 if _PyObject_VAR_SIZE._type_size_t is None:
473 _PyObject_VAR_SIZE._type_size_t = gdb.lookup_type('size_t')
474
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000475 return ( ( typeobj.field('tp_basicsize') +
476 nitems * typeobj.field('tp_itemsize') +
Victor Stinner4e75ca82016-04-20 18:07:21 +0200477 (_sizeof_void_p() - 1)
478 ) & ~(_sizeof_void_p() - 1)
Victor Stinnerd2084162011-12-19 13:42:24 +0100479 ).cast(_PyObject_VAR_SIZE._type_size_t)
480_PyObject_VAR_SIZE._type_size_t = None
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000481
482class HeapTypeObjectPtr(PyObjectPtr):
483 _typename = 'PyObject'
484
485 def get_attr_dict(self):
486 '''
487 Get the PyDictObject ptr representing the attribute dictionary
488 (or None if there's a problem)
489 '''
490 try:
491 typeobj = self.type()
492 dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
493 if dictoffset != 0:
494 if dictoffset < 0:
495 type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
496 tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
497 if tsize < 0:
498 tsize = -tsize
499 size = _PyObject_VAR_SIZE(typeobj, tsize)
500 dictoffset += size
501 assert dictoffset > 0
Victor Stinner4e75ca82016-04-20 18:07:21 +0200502 assert dictoffset % _sizeof_void_p() == 0
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000503
Victor Stinner4e75ca82016-04-20 18:07:21 +0200504 dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000505 PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
506 dictptr = dictptr.cast(PyObjectPtrPtr)
507 return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
508 except RuntimeError:
509 # Corrupt data somewhere; fail safe
510 pass
511
512 # Not found, or some kind of error:
513 return None
514
515 def proxyval(self, visited):
516 '''
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100517 Support for classes.
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000518
519 Currently we just locate the dictionary using a transliteration to
520 python of _PyObject_GetDictPtr, ignoring descriptors
521 '''
522 # Guard against infinite loops:
523 if self.as_address() in visited:
524 return ProxyAlreadyVisited('<...>')
525 visited.add(self.as_address())
526
527 pyop_attr_dict = self.get_attr_dict()
528 if pyop_attr_dict:
529 attr_dict = pyop_attr_dict.proxyval(visited)
530 else:
531 attr_dict = {}
532 tp_name = self.safe_tp_name()
533
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100534 # Class:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000535 return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
536
537 def write_repr(self, out, visited):
538 # Guard against infinite loops:
539 if self.as_address() in visited:
540 out.write('<...>')
541 return
542 visited.add(self.as_address())
543
544 pyop_attrdict = self.get_attr_dict()
545 _write_instance_repr(out, visited,
546 self.safe_tp_name(), pyop_attrdict, self.as_address())
547
548class ProxyException(Exception):
549 def __init__(self, tp_name, args):
550 self.tp_name = tp_name
551 self.args = args
552
553 def __repr__(self):
554 return '%s%r' % (self.tp_name, self.args)
555
556class PyBaseExceptionObjectPtr(PyObjectPtr):
557 """
558 Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception
559 within the process being debugged.
560 """
561 _typename = 'PyBaseExceptionObject'
562
563 def proxyval(self, visited):
564 # Guard against infinite loops:
565 if self.as_address() in visited:
566 return ProxyAlreadyVisited('(...)')
567 visited.add(self.as_address())
568 arg_proxy = self.pyop_field('args').proxyval(visited)
569 return ProxyException(self.safe_tp_name(),
570 arg_proxy)
571
572 def write_repr(self, out, visited):
573 # Guard against infinite loops:
574 if self.as_address() in visited:
575 out.write('(...)')
576 return
577 visited.add(self.as_address())
578
579 out.write(self.safe_tp_name())
580 self.write_field_repr('args', out, visited)
581
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000582class PyClassObjectPtr(PyObjectPtr):
583 """
584 Class wrapping a gdb.Value that's a PyClassObject* i.e. a <classobj>
585 instance within the process being debugged.
586 """
587 _typename = 'PyClassObject'
588
589
590class BuiltInFunctionProxy(object):
591 def __init__(self, ml_name):
592 self.ml_name = ml_name
593
594 def __repr__(self):
595 return "<built-in function %s>" % self.ml_name
596
597class BuiltInMethodProxy(object):
598 def __init__(self, ml_name, pyop_m_self):
599 self.ml_name = ml_name
600 self.pyop_m_self = pyop_m_self
601
602 def __repr__(self):
603 return ('<built-in method %s of %s object at remote 0x%x>'
604 % (self.ml_name,
605 self.pyop_m_self.safe_tp_name(),
606 self.pyop_m_self.as_address())
607 )
608
609class PyCFunctionObjectPtr(PyObjectPtr):
610 """
611 Class wrapping a gdb.Value that's a PyCFunctionObject*
612 (see Include/methodobject.h and Objects/methodobject.c)
613 """
614 _typename = 'PyCFunctionObject'
615
616 def proxyval(self, visited):
617 m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
618 ml_name = m_ml['ml_name'].string()
619
620 pyop_m_self = self.pyop_field('m_self')
621 if pyop_m_self.is_null():
622 return BuiltInFunctionProxy(ml_name)
623 else:
624 return BuiltInMethodProxy(ml_name, pyop_m_self)
625
626
627class PyCodeObjectPtr(PyObjectPtr):
628 """
629 Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
630 within the process being debugged.
631 """
632 _typename = 'PyCodeObject'
633
634 def addr2line(self, addrq):
635 '''
636 Get the line number for a given bytecode offset
637
638 Analogous to PyCode_Addr2Line; translated from pseudocode in
639 Objects/lnotab_notes.txt
640 '''
641 co_lnotab = self.pyop_field('co_lnotab').proxyval(set())
642
643 # Initialize lineno to co_firstlineno as per PyCode_Addr2Line
644 # not 0, as lnotab_notes.txt has it:
645 lineno = int_from_int(self.field('co_firstlineno'))
646
647 addr = 0
648 for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
649 addr += ord(addr_incr)
650 if addr > addrq:
651 return lineno
652 lineno += ord(line_incr)
653 return lineno
654
655
656class PyDictObjectPtr(PyObjectPtr):
657 """
658 Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
659 within the process being debugged.
660 """
661 _typename = 'PyDictObject'
662
663 def iteritems(self):
664 '''
665 Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
Ezio Melotti7c4a7e62013-08-26 01:32:56 +0300666 analogous to dict.iteritems()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000667 '''
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400668 keys = self.field('ma_keys')
669 values = self.field('ma_values')
INADA Naokid7d2bc82016-11-22 19:40:58 +0900670 entries, nentries = self._get_entries(keys)
671 for i in safe_range(nentries):
672 ep = entries[i]
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400673 if long(values):
674 pyop_value = PyObjectPtr.from_pyobject_ptr(values[i])
675 else:
676 pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000677 if not pyop_value.is_null():
678 pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
679 yield (pyop_key, pyop_value)
680
681 def proxyval(self, visited):
682 # Guard against infinite loops:
683 if self.as_address() in visited:
684 return ProxyAlreadyVisited('{...}')
685 visited.add(self.as_address())
686
687 result = {}
688 for pyop_key, pyop_value in self.iteritems():
689 proxy_key = pyop_key.proxyval(visited)
690 proxy_value = pyop_value.proxyval(visited)
691 result[proxy_key] = proxy_value
692 return result
693
694 def write_repr(self, out, visited):
695 # Guard against infinite loops:
696 if self.as_address() in visited:
697 out.write('{...}')
698 return
699 visited.add(self.as_address())
700
701 out.write('{')
702 first = True
703 for pyop_key, pyop_value in self.iteritems():
704 if not first:
705 out.write(', ')
706 first = False
707 pyop_key.write_repr(out, visited)
708 out.write(': ')
709 pyop_value.write_repr(out, visited)
710 out.write('}')
711
INADA Naokid7d2bc82016-11-22 19:40:58 +0900712 def _get_entries(self, keys):
Victor Stinner3a5d79f2016-11-22 13:09:39 +0100713 dk_nentries = int(keys['dk_nentries'])
INADA Naokid7d2bc82016-11-22 19:40:58 +0900714 dk_size = int(keys['dk_size'])
715 try:
716 # <= Python 3.5
717 return keys['dk_entries'], dk_size
Lev Abalkin661ca882017-03-01 13:16:23 -0500718 except RuntimeError:
INADA Naokid7d2bc82016-11-22 19:40:58 +0900719 # >= Python 3.6
720 pass
721
722 if dk_size <= 0xFF:
723 offset = dk_size
724 elif dk_size <= 0xFFFF:
725 offset = 2 * dk_size
726 elif dk_size <= 0xFFFFFFFF:
727 offset = 4 * dk_size
728 else:
729 offset = 8 * dk_size
730
Victor Stinner3a5d79f2016-11-22 13:09:39 +0100731 ent_addr = keys['dk_indices']['as_1'].address
732 ent_addr = ent_addr.cast(_type_unsigned_char_ptr()) + offset
INADA Naokid7d2bc82016-11-22 19:40:58 +0900733 ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer()
Victor Stinner3a5d79f2016-11-22 13:09:39 +0100734 ent_addr = ent_addr.cast(ent_ptr_t)
735
736 return ent_addr, dk_nentries
INADA Naokid7d2bc82016-11-22 19:40:58 +0900737
738
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000739class PyListObjectPtr(PyObjectPtr):
740 _typename = 'PyListObject'
741
742 def __getitem__(self, i):
743 # Get the gdb.Value for the (PyObject*) with the given index:
744 field_ob_item = self.field('ob_item')
745 return field_ob_item[i]
746
747 def proxyval(self, visited):
748 # Guard against infinite loops:
749 if self.as_address() in visited:
750 return ProxyAlreadyVisited('[...]')
751 visited.add(self.as_address())
752
753 result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
754 for i in safe_range(int_from_int(self.field('ob_size')))]
755 return result
756
757 def write_repr(self, out, visited):
758 # Guard against infinite loops:
759 if self.as_address() in visited:
760 out.write('[...]')
761 return
762 visited.add(self.as_address())
763
764 out.write('[')
765 for i in safe_range(int_from_int(self.field('ob_size'))):
766 if i > 0:
767 out.write(', ')
768 element = PyObjectPtr.from_pyobject_ptr(self[i])
769 element.write_repr(out, visited)
770 out.write(']')
771
772class PyLongObjectPtr(PyObjectPtr):
773 _typename = 'PyLongObject'
774
775 def proxyval(self, visited):
776 '''
777 Python's Include/longobjrep.h has this declaration:
778 struct _longobject {
779 PyObject_VAR_HEAD
780 digit ob_digit[1];
781 };
782
783 with this description:
784 The absolute value of a number is equal to
785 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
786 Negative numbers are represented with ob_size < 0;
787 zero is represented by ob_size == 0.
788
789 where SHIFT can be either:
790 #define PyLong_SHIFT 30
791 #define PyLong_SHIFT 15
792 '''
793 ob_size = long(self.field('ob_size'))
794 if ob_size == 0:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100795 return 0
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000796
797 ob_digit = self.field('ob_digit')
798
799 if gdb.lookup_type('digit').sizeof == 2:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100800 SHIFT = 15
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000801 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100802 SHIFT = 30
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000803
804 digits = [long(ob_digit[i]) * 2**(SHIFT*i)
805 for i in safe_range(abs(ob_size))]
806 result = sum(digits)
807 if ob_size < 0:
808 result = -result
809 return result
810
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000811 def write_repr(self, out, visited):
812 # Write this out as a Python 3 int literal, i.e. without the "L" suffix
813 proxy = self.proxyval(visited)
814 out.write("%s" % proxy)
815
816
817class PyBoolObjectPtr(PyLongObjectPtr):
818 """
819 Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
820 <bool> instances (Py_True/Py_False) within the process being debugged.
821 """
822 def proxyval(self, visited):
823 if PyLongObjectPtr.proxyval(self, visited):
824 return True
825 else:
826 return False
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000827
828class PyNoneStructPtr(PyObjectPtr):
829 """
830 Class wrapping a gdb.Value that's a PyObject* pointing to the
831 singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type
832 """
833 _typename = 'PyObject'
834
835 def proxyval(self, visited):
836 return None
837
838
839class PyFrameObjectPtr(PyObjectPtr):
840 _typename = 'PyFrameObject'
841
Victor Stinnerd2084162011-12-19 13:42:24 +0100842 def __init__(self, gdbval, cast_to=None):
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000843 PyObjectPtr.__init__(self, gdbval, cast_to)
844
845 if not self.is_optimized_out():
846 self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
847 self.co_name = self.co.pyop_field('co_name')
848 self.co_filename = self.co.pyop_field('co_filename')
849
850 self.f_lineno = int_from_int(self.field('f_lineno'))
851 self.f_lasti = int_from_int(self.field('f_lasti'))
852 self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
853 self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))
854
855 def iter_locals(self):
856 '''
857 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
858 the local variables of this frame
859 '''
860 if self.is_optimized_out():
861 return
862
863 f_localsplus = self.field('f_localsplus')
864 for i in safe_range(self.co_nlocals):
865 pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
866 if not pyop_value.is_null():
867 pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
868 yield (pyop_name, pyop_value)
869
870 def iter_globals(self):
871 '''
872 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
873 the global variables of this frame
874 '''
875 if self.is_optimized_out():
Victor Stinnerd2084162011-12-19 13:42:24 +0100876 return ()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000877
878 pyop_globals = self.pyop_field('f_globals')
879 return pyop_globals.iteritems()
880
881 def iter_builtins(self):
882 '''
883 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
884 the builtin variables
885 '''
886 if self.is_optimized_out():
Victor Stinnerd2084162011-12-19 13:42:24 +0100887 return ()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000888
889 pyop_builtins = self.pyop_field('f_builtins')
890 return pyop_builtins.iteritems()
891
892 def get_var_by_name(self, name):
893 '''
894 Look for the named local variable, returning a (PyObjectPtr, scope) pair
895 where scope is a string 'local', 'global', 'builtin'
896
897 If not found, return (None, None)
898 '''
899 for pyop_name, pyop_value in self.iter_locals():
900 if name == pyop_name.proxyval(set()):
901 return pyop_value, 'local'
902 for pyop_name, pyop_value in self.iter_globals():
903 if name == pyop_name.proxyval(set()):
904 return pyop_value, 'global'
905 for pyop_name, pyop_value in self.iter_builtins():
906 if name == pyop_name.proxyval(set()):
907 return pyop_value, 'builtin'
908 return None, None
909
910 def filename(self):
911 '''Get the path of the current Python source file, as a string'''
912 if self.is_optimized_out():
913 return '(frame information optimized out)'
914 return self.co_filename.proxyval(set())
915
916 def current_line_num(self):
917 '''Get current line number as an integer (1-based)
918
919 Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
920
921 See Objects/lnotab_notes.txt
922 '''
923 if self.is_optimized_out():
924 return None
925 f_trace = self.field('f_trace')
926 if long(f_trace) != 0:
927 # we have a non-NULL f_trace:
928 return self.f_lineno
929 else:
930 #try:
931 return self.co.addr2line(self.f_lasti)
932 #except ValueError:
933 # return self.f_lineno
934
935 def current_line(self):
936 '''Get the text of the current source line as a string, with a trailing
937 newline character'''
938 if self.is_optimized_out():
939 return '(frame information optimized out)'
Victor Stinner6ffbee72010-10-17 19:35:30 +0000940 filename = self.filename()
Victor Stinnerd57c5c82011-07-01 12:57:44 +0200941 try:
942 f = open(os_fsencode(filename), 'r')
943 except IOError:
944 return None
945 with f:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000946 all_lines = f.readlines()
947 # Convert from 1-based current_line_num to 0-based list offset:
948 return all_lines[self.current_line_num()-1]
949
950 def write_repr(self, out, visited):
951 if self.is_optimized_out():
952 out.write('(frame information optimized out)')
953 return
954 out.write('Frame 0x%x, for file %s, line %i, in %s ('
955 % (self.as_address(),
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000956 self.co_filename.proxyval(visited),
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000957 self.current_line_num(),
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000958 self.co_name.proxyval(visited)))
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000959 first = True
960 for pyop_name, pyop_value in self.iter_locals():
961 if not first:
962 out.write(', ')
963 first = False
964
965 out.write(pyop_name.proxyval(visited))
966 out.write('=')
967 pyop_value.write_repr(out, visited)
968
969 out.write(')')
970
Victor Stinnere670c882011-05-13 17:40:15 +0200971 def print_traceback(self):
972 if self.is_optimized_out():
973 sys.stdout.write(' (frame information optimized out)\n')
Victor Stinnerd2084162011-12-19 13:42:24 +0100974 return
Victor Stinnere670c882011-05-13 17:40:15 +0200975 visited = set()
976 sys.stdout.write(' File "%s", line %i, in %s\n'
977 % (self.co_filename.proxyval(visited),
978 self.current_line_num(),
979 self.co_name.proxyval(visited)))
980
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000981class PySetObjectPtr(PyObjectPtr):
982 _typename = 'PySetObject'
983
Antoine Pitrou9d952542013-08-24 21:07:07 +0200984 @classmethod
985 def _dummy_key(self):
986 return gdb.lookup_global_symbol('_PySet_Dummy').value()
987
988 def __iter__(self):
989 dummy_ptr = self._dummy_key()
990 table = self.field('table')
991 for i in safe_range(self.field('mask') + 1):
992 setentry = table[i]
993 key = setentry['key']
994 if key != 0 and key != dummy_ptr:
995 yield PyObjectPtr.from_pyobject_ptr(key)
996
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000997 def proxyval(self, visited):
998 # Guard against infinite loops:
999 if self.as_address() in visited:
1000 return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
1001 visited.add(self.as_address())
1002
Antoine Pitrou9d952542013-08-24 21:07:07 +02001003 members = (key.proxyval(visited) for key in self)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001004 if self.safe_tp_name() == 'frozenset':
1005 return frozenset(members)
1006 else:
1007 return set(members)
1008
1009 def write_repr(self, out, visited):
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001010 # Emulate Python 3's set_repr
1011 tp_name = self.safe_tp_name()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001012
1013 # Guard against infinite loops:
1014 if self.as_address() in visited:
1015 out.write('(...)')
1016 return
1017 visited.add(self.as_address())
1018
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001019 # Python 3's set_repr special-cases the empty set:
1020 if not self.field('used'):
1021 out.write(tp_name)
1022 out.write('()')
1023 return
1024
1025 # Python 3 uses {} for set literals:
1026 if tp_name != 'set':
1027 out.write(tp_name)
1028 out.write('(')
1029
1030 out.write('{')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001031 first = True
Antoine Pitrou9d952542013-08-24 21:07:07 +02001032 for key in self:
1033 if not first:
1034 out.write(', ')
1035 first = False
1036 key.write_repr(out, visited)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001037 out.write('}')
1038
1039 if tp_name != 'set':
1040 out.write(')')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001041
1042
Victor Stinner67df3a42010-04-21 13:53:05 +00001043class PyBytesObjectPtr(PyObjectPtr):
1044 _typename = 'PyBytesObject'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001045
1046 def __str__(self):
1047 field_ob_size = self.field('ob_size')
1048 field_ob_sval = self.field('ob_sval')
Victor Stinner4e75ca82016-04-20 18:07:21 +02001049 char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001050 return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
1051
1052 def proxyval(self, visited):
1053 return str(self)
1054
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001055 def write_repr(self, out, visited):
1056 # Write this out as a Python 3 bytes literal, i.e. with a "b" prefix
1057
1058 # Get a PyStringObject* within the Python 2 gdb process:
1059 proxy = self.proxyval(visited)
1060
1061 # Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr
1062 # to Python 2 code:
1063 quote = "'"
1064 if "'" in proxy and not '"' in proxy:
1065 quote = '"'
1066 out.write('b')
1067 out.write(quote)
1068 for byte in proxy:
1069 if byte == quote or byte == '\\':
1070 out.write('\\')
1071 out.write(byte)
1072 elif byte == '\t':
1073 out.write('\\t')
1074 elif byte == '\n':
1075 out.write('\\n')
1076 elif byte == '\r':
1077 out.write('\\r')
1078 elif byte < ' ' or ord(byte) >= 0x7f:
1079 out.write('\\x')
1080 out.write(hexdigits[(ord(byte) & 0xf0) >> 4])
1081 out.write(hexdigits[ord(byte) & 0xf])
1082 else:
1083 out.write(byte)
1084 out.write(quote)
1085
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001086class PyTupleObjectPtr(PyObjectPtr):
1087 _typename = 'PyTupleObject'
1088
1089 def __getitem__(self, i):
1090 # Get the gdb.Value for the (PyObject*) with the given index:
1091 field_ob_item = self.field('ob_item')
1092 return field_ob_item[i]
1093
1094 def proxyval(self, visited):
1095 # Guard against infinite loops:
1096 if self.as_address() in visited:
1097 return ProxyAlreadyVisited('(...)')
1098 visited.add(self.as_address())
1099
Jon Dufresne39726282017-05-18 07:35:54 -07001100 result = tuple(PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
1101 for i in safe_range(int_from_int(self.field('ob_size'))))
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001102 return result
1103
1104 def write_repr(self, out, visited):
1105 # Guard against infinite loops:
1106 if self.as_address() in visited:
1107 out.write('(...)')
1108 return
1109 visited.add(self.as_address())
1110
1111 out.write('(')
1112 for i in safe_range(int_from_int(self.field('ob_size'))):
1113 if i > 0:
1114 out.write(', ')
1115 element = PyObjectPtr.from_pyobject_ptr(self[i])
1116 element.write_repr(out, visited)
1117 if self.field('ob_size') == 1:
1118 out.write(',)')
1119 else:
1120 out.write(')')
1121
1122class PyTypeObjectPtr(PyObjectPtr):
1123 _typename = 'PyTypeObject'
1124
1125
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001126def _unichr_is_printable(char):
1127 # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
1128 if char == u" ":
1129 return True
1130 import unicodedata
Antoine Pitroub41e1282010-09-08 20:57:48 +00001131 return unicodedata.category(char) not in ("C", "Z")
1132
1133if sys.maxunicode >= 0x10000:
1134 _unichr = unichr
1135else:
1136 # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
1137 def _unichr(x):
1138 if x < 0x10000:
1139 return unichr(x)
1140 x -= 0x10000
1141 ch1 = 0xD800 | (x >> 10)
1142 ch2 = 0xDC00 | (x & 0x3FF)
1143 return unichr(ch1) + unichr(ch2)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001144
1145
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001146class PyUnicodeObjectPtr(PyObjectPtr):
1147 _typename = 'PyUnicodeObject'
1148
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001149 def char_width(self):
1150 _type_Py_UNICODE = gdb.lookup_type('Py_UNICODE')
1151 return _type_Py_UNICODE.sizeof
1152
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001153 def proxyval(self, visited):
Victor Stinner0c4fbff2011-12-08 00:08:22 +01001154 global _is_pep393
1155 if _is_pep393 is None:
1156 fields = gdb.lookup_type('PyUnicodeObject').target().fields()
1157 _is_pep393 = 'data' in [f.name for f in fields]
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001158 if _is_pep393:
1159 # Python 3.3 and newer
1160 may_have_surrogates = False
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001161 compact = self.field('_base')
1162 ascii = compact['_base']
1163 state = ascii['state']
Victor Stinnera3b334d2011-10-03 13:53:37 +02001164 is_compact_ascii = (int(state['ascii']) and int(state['compact']))
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001165 if not int(state['ready']):
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001166 # string is not ready
Victor Stinnerf16a3502011-11-04 22:34:01 +01001167 field_length = long(compact['wstr_length'])
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001168 may_have_surrogates = True
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001169 field_str = ascii['wstr']
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001170 else:
Victor Stinnerf16a3502011-11-04 22:34:01 +01001171 field_length = long(ascii['length'])
Victor Stinnera3b334d2011-10-03 13:53:37 +02001172 if is_compact_ascii:
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001173 field_str = ascii.address + 1
1174 elif int(state['compact']):
1175 field_str = compact.address + 1
1176 else:
1177 field_str = self.field('data')['any']
1178 repr_kind = int(state['kind'])
1179 if repr_kind == 1:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001180 field_str = field_str.cast(_type_unsigned_char_ptr())
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001181 elif repr_kind == 2:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001182 field_str = field_str.cast(_type_unsigned_short_ptr())
Antoine Pitrou3c0c5f22011-10-08 19:33:24 +02001183 elif repr_kind == 4:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001184 field_str = field_str.cast(_type_unsigned_int_ptr())
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001185 else:
1186 # Python 3.2 and earlier
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001187 field_length = long(self.field('length'))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001188 field_str = self.field('str')
1189 may_have_surrogates = self.char_width() == 2
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001190
1191 # Gather a list of ints from the Py_UNICODE array; these are either
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001192 # UCS-1, UCS-2 or UCS-4 code points:
1193 if not may_have_surrogates:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001194 Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
1195 else:
1196 # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
1197 # inferior process: we must join surrogate pairs.
1198 Py_UNICODEs = []
1199 i = 0
Antoine Pitroub1856d72010-09-08 21:07:40 +00001200 limit = safety_limit(field_length)
1201 while i < limit:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001202 ucs = int(field_str[i])
1203 i += 1
1204 if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
1205 Py_UNICODEs.append(ucs)
1206 continue
1207 # This could be a surrogate pair.
1208 ucs2 = int(field_str[i])
1209 if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
1210 continue
1211 code = (ucs & 0x03FF) << 10
1212 code |= ucs2 & 0x03FF
1213 code += 0x00010000
1214 Py_UNICODEs.append(code)
1215 i += 1
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001216
1217 # Convert the int code points to unicode characters, and generate a
Antoine Pitroub41e1282010-09-08 20:57:48 +00001218 # local unicode instance.
1219 # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
Victor Stinnerd8a5cc92013-04-11 21:37:45 +02001220 result = u''.join([
1221 (_unichr(ucs) if ucs <= 0x10ffff else '\ufffd')
1222 for ucs in Py_UNICODEs])
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001223 return result
1224
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001225 def write_repr(self, out, visited):
1226 # Write this out as a Python 3 str literal, i.e. without a "u" prefix
1227
1228 # Get a PyUnicodeObject* within the Python 2 gdb process:
1229 proxy = self.proxyval(visited)
1230
1231 # Transliteration of Python 3's Object/unicodeobject.c:unicode_repr
1232 # to Python 2:
1233 if "'" in proxy and '"' not in proxy:
1234 quote = '"'
1235 else:
1236 quote = "'"
1237 out.write(quote)
1238
1239 i = 0
1240 while i < len(proxy):
1241 ch = proxy[i]
1242 i += 1
1243
1244 # Escape quotes and backslashes
1245 if ch == quote or ch == '\\':
1246 out.write('\\')
1247 out.write(ch)
1248
1249 # Map special whitespace to '\t', \n', '\r'
1250 elif ch == '\t':
1251 out.write('\\t')
1252 elif ch == '\n':
1253 out.write('\\n')
1254 elif ch == '\r':
1255 out.write('\\r')
1256
1257 # Map non-printable US ASCII to '\xhh' */
1258 elif ch < ' ' or ch == 0x7F:
1259 out.write('\\x')
1260 out.write(hexdigits[(ord(ch) >> 4) & 0x000F])
1261 out.write(hexdigits[ord(ch) & 0x000F])
1262
1263 # Copy ASCII characters as-is
1264 elif ord(ch) < 0x7F:
1265 out.write(ch)
1266
1267 # Non-ASCII characters
1268 else:
Victor Stinner150016f2010-05-19 23:04:56 +00001269 ucs = ch
Antoine Pitroub41e1282010-09-08 20:57:48 +00001270 ch2 = None
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001271 if sys.maxunicode < 0x10000:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001272 # If sizeof(Py_UNICODE) is 2 here (in gdb), join
1273 # surrogate pairs before calling _unichr_is_printable.
Victor Stinner150016f2010-05-19 23:04:56 +00001274 if (i < len(proxy)
1275 and 0xD800 <= ord(ch) < 0xDC00 \
1276 and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001277 ch2 = proxy[i]
Antoine Pitroub41e1282010-09-08 20:57:48 +00001278 ucs = ch + ch2
Victor Stinner150016f2010-05-19 23:04:56 +00001279 i += 1
Victor Stinner150016f2010-05-19 23:04:56 +00001280
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001281 # Unfortuately, Python 2's unicode type doesn't seem
1282 # to expose the "isprintable" method
Victor Stinner150016f2010-05-19 23:04:56 +00001283 printable = _unichr_is_printable(ucs)
1284 if printable:
1285 try:
1286 ucs.encode(ENCODING)
1287 except UnicodeEncodeError:
1288 printable = False
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001289
1290 # Map Unicode whitespace and control characters
1291 # (categories Z* and C* except ASCII space)
Victor Stinner150016f2010-05-19 23:04:56 +00001292 if not printable:
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001293 if ch2 is not None:
1294 # Match Python 3's representation of non-printable
1295 # wide characters.
1296 code = (ord(ch) & 0x03FF) << 10
1297 code |= ord(ch2) & 0x03FF
1298 code += 0x00010000
1299 else:
1300 code = ord(ucs)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001301
1302 # Map 8-bit characters to '\\xhh'
Victor Stinner150016f2010-05-19 23:04:56 +00001303 if code <= 0xff:
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001304 out.write('\\x')
Victor Stinner150016f2010-05-19 23:04:56 +00001305 out.write(hexdigits[(code >> 4) & 0x000F])
1306 out.write(hexdigits[code & 0x000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001307 # Map 21-bit characters to '\U00xxxxxx'
Victor Stinner150016f2010-05-19 23:04:56 +00001308 elif code >= 0x10000:
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001309 out.write('\\U')
Victor Stinner150016f2010-05-19 23:04:56 +00001310 out.write(hexdigits[(code >> 28) & 0x0000000F])
1311 out.write(hexdigits[(code >> 24) & 0x0000000F])
1312 out.write(hexdigits[(code >> 20) & 0x0000000F])
1313 out.write(hexdigits[(code >> 16) & 0x0000000F])
1314 out.write(hexdigits[(code >> 12) & 0x0000000F])
1315 out.write(hexdigits[(code >> 8) & 0x0000000F])
1316 out.write(hexdigits[(code >> 4) & 0x0000000F])
1317 out.write(hexdigits[code & 0x0000000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001318 # Map 16-bit characters to '\uxxxx'
1319 else:
1320 out.write('\\u')
Victor Stinner150016f2010-05-19 23:04:56 +00001321 out.write(hexdigits[(code >> 12) & 0x000F])
1322 out.write(hexdigits[(code >> 8) & 0x000F])
1323 out.write(hexdigits[(code >> 4) & 0x000F])
1324 out.write(hexdigits[code & 0x000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001325 else:
1326 # Copy characters as-is
1327 out.write(ch)
Antoine Pitroub41e1282010-09-08 20:57:48 +00001328 if ch2 is not None:
Victor Stinner150016f2010-05-19 23:04:56 +00001329 out.write(ch2)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001330
1331 out.write(quote)
1332
1333
Victor Stinner61108332017-02-01 16:29:54 +01001334class 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)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001367
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001368
1369def int_from_int(gdbval):
1370 return int(str(gdbval))
1371
1372
1373def stringify(val):
1374 # TODO: repr() puts everything on one line; pformat can be nicer, but
1375 # can lead to v.long results; this function isolates the choice
1376 if True:
1377 return repr(val)
1378 else:
1379 from pprint import pformat
1380 return pformat(val)
1381
1382
1383class PyObjectPtrPrinter:
1384 "Prints a (PyObject*)"
1385
1386 def __init__ (self, gdbval):
1387 self.gdbval = gdbval
1388
1389 def to_string (self):
1390 pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval)
1391 if True:
1392 return pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1393 else:
1394 # Generate full proxy value then stringify it.
1395 # Doing so could be expensive
1396 proxyval = pyop.proxyval(set())
1397 return stringify(proxyval)
1398
1399def pretty_printer_lookup(gdbval):
1400 type = gdbval.type.unqualified()
Victor Stinner61108332017-02-01 16:29:54 +01001401 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)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001408
1409"""
1410During development, I've been manually invoking the code in this way:
1411(gdb) python
1412
1413import sys
1414sys.path.append('/home/david/coding/python-gdb')
1415import libpython
1416end
1417
1418then reloading it after each edit like this:
1419(gdb) python reload(libpython)
1420
1421The following code should ensure that the prettyprinter is registered
1422if the code is autoloaded by gdb when visiting libpython.so, provided
1423that this python file is installed to the same path as the library (or its
1424.debug file) plus a "-gdb.py" suffix, e.g:
1425 /usr/lib/libpython2.6.so.1.0-gdb.py
1426 /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
1427"""
1428def register (obj):
Benjamin Petersonb29614e2012-10-09 11:16:03 -04001429 if obj is None:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001430 obj = gdb
1431
1432 # Wire up the pretty-printer
1433 obj.pretty_printers.append(pretty_printer_lookup)
1434
1435register (gdb.current_objfile ())
1436
1437
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001438
1439# Unfortunately, the exact API exposed by the gdb module varies somewhat
1440# from build to build
1441# See http://bugs.python.org/issue8279?#msg102276
1442
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001443class Frame(object):
1444 '''
1445 Wrapper for gdb.Frame, adding various methods
1446 '''
1447 def __init__(self, gdbframe):
1448 self._gdbframe = gdbframe
1449
1450 def older(self):
1451 older = self._gdbframe.older()
1452 if older:
1453 return Frame(older)
1454 else:
1455 return None
1456
1457 def newer(self):
1458 newer = self._gdbframe.newer()
1459 if newer:
1460 return Frame(newer)
1461 else:
1462 return None
1463
1464 def select(self):
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001465 '''If supported, select this frame and return True; return False if unsupported
1466
1467 Not all builds have a gdb.Frame.select method; seems to be present on Fedora 12
1468 onwards, but absent on Ubuntu buildbot'''
1469 if not hasattr(self._gdbframe, 'select'):
1470 print ('Unable to select frame: '
1471 'this build of gdb does not expose a gdb.Frame.select method')
1472 return False
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001473 self._gdbframe.select()
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001474 return True
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001475
1476 def get_index(self):
1477 '''Calculate index of frame, starting at 0 for the newest frame within
1478 this thread'''
1479 index = 0
1480 # Go down until you reach the newest frame:
1481 iter_frame = self
1482 while iter_frame.newer():
1483 index += 1
1484 iter_frame = iter_frame.newer()
1485 return index
1486
David Malcolm8d37ffa2012-06-27 14:15:34 -04001487 # We divide frames into:
1488 # - "python frames":
1489 # - "bytecode frames" i.e. PyEval_EvalFrameEx
1490 # - "other python frames": things that are of interest from a python
1491 # POV, but aren't bytecode (e.g. GC, GIL)
1492 # - everything else
1493
1494 def is_python_frame(self):
1495 '''Is this a PyEval_EvalFrameEx frame, or some other important
1496 frame? (see is_other_python_frame for what "important" means in this
1497 context)'''
1498 if self.is_evalframeex():
1499 return True
1500 if self.is_other_python_frame():
1501 return True
1502 return False
1503
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001504 def is_evalframeex(self):
Bruno "Polaco" Penteado2e0f4db2017-08-14 23:14:17 +01001505 '''Is this a PyEval_EvalFrameEx or _PyEval_EvalFrameDefault (PEP 0523)
1506 frame?'''
1507 if self._gdbframe.name() in ('PyEval_EvalFrameEx',
1508 '_PyEval_EvalFrameDefault'):
Victor Stinner50eb60e2010-04-20 22:32:07 +00001509 '''
1510 I believe we also need to filter on the inline
1511 struct frame_id.inline_depth, only regarding frames with
1512 an inline depth of 0 as actually being this function
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001513
Victor Stinner50eb60e2010-04-20 22:32:07 +00001514 So we reject those with type gdb.INLINE_FRAME
1515 '''
1516 if self._gdbframe.type() == gdb.NORMAL_FRAME:
1517 # We have a PyEval_EvalFrameEx frame:
1518 return True
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001519
1520 return False
1521
David Malcolm8d37ffa2012-06-27 14:15:34 -04001522 def is_other_python_frame(self):
1523 '''Is this frame worth displaying in python backtraces?
1524 Examples:
1525 - waiting on the GIL
1526 - garbage-collecting
1527 - within a CFunction
1528 If it is, return a descriptive string
1529 For other frames, return False
1530 '''
1531 if self.is_waiting_for_gil():
1532 return 'Waiting for the GIL'
Victor Stinnereae64fd2016-11-22 22:53:18 +01001533
1534 if self.is_gc_collect():
David Malcolm8d37ffa2012-06-27 14:15:34 -04001535 return 'Garbage-collecting'
Victor Stinnereae64fd2016-11-22 22:53:18 +01001536
1537 # Detect invocations of PyCFunction instances:
Victor Stinnerfa025f12017-01-18 17:20:01 +01001538 frame = self._gdbframe
1539 caller = frame.name()
Victor Stinnereae64fd2016-11-22 22:53:18 +01001540 if not caller:
1541 return False
1542
Victor Stinnerfa025f12017-01-18 17:20:01 +01001543 if caller in ('_PyCFunction_FastCallDict',
1544 '_PyCFunction_FastCallKeywords'):
INADA Naoki5566bbb2017-02-03 07:43:03 +09001545 arg_name = 'func'
Victor Stinnereae64fd2016-11-22 22:53:18 +01001546 # Within that frame:
1547 # "func" is the local containing the PyObject* of the
1548 # PyCFunctionObject instance
1549 # "f" is the same value, but cast to (PyCFunctionObject*)
1550 # "self" is the (PyObject*) of the 'self'
1551 try:
1552 # Use the prettyprinter for the func:
Victor Stinnerfa025f12017-01-18 17:20:01 +01001553 func = frame.read_var(arg_name)
Victor Stinnereae64fd2016-11-22 22:53:18 +01001554 return str(func)
1555 except RuntimeError:
Victor Stinnerfa025f12017-01-18 17:20:01 +01001556 return 'PyCFunction invocation (unable to read %s)' % arg_name
David Malcolm8d37ffa2012-06-27 14:15:34 -04001557
Victor Stinner61108332017-02-01 16:29:54 +01001558 if caller == 'wrapper_call':
1559 try:
1560 func = frame.read_var('wp')
1561 return str(func)
1562 except RuntimeError:
1563 return '<wrapper_call invocation>'
1564
David Malcolm8d37ffa2012-06-27 14:15:34 -04001565 # This frame isn't worth reporting:
1566 return False
1567
1568 def is_waiting_for_gil(self):
1569 '''Is this frame waiting on the GIL?'''
1570 # This assumes the _POSIX_THREADS version of Python/ceval_gil.h:
1571 name = self._gdbframe.name()
1572 if name:
David Malcolmd08b2102013-05-06 14:47:15 -04001573 return 'pthread_cond_timedwait' in name
David Malcolm8d37ffa2012-06-27 14:15:34 -04001574
1575 def is_gc_collect(self):
Ezio Melotti3f5db392013-01-27 06:20:14 +02001576 '''Is this frame "collect" within the garbage-collector?'''
David Malcolm8d37ffa2012-06-27 14:15:34 -04001577 return self._gdbframe.name() == 'collect'
1578
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001579 def get_pyop(self):
1580 try:
1581 f = self._gdbframe.read_var('f')
Victor Stinnerd2084162011-12-19 13:42:24 +01001582 frame = PyFrameObjectPtr.from_pyobject_ptr(f)
1583 if not frame.is_optimized_out():
1584 return frame
1585 # gdb is unable to get the "f" argument of PyEval_EvalFrameEx()
1586 # because it was "optimized out". Try to get "f" from the frame
1587 # of the caller, PyEval_EvalCodeEx().
1588 orig_frame = frame
1589 caller = self._gdbframe.older()
1590 if caller:
1591 f = caller.read_var('f')
1592 frame = PyFrameObjectPtr.from_pyobject_ptr(f)
1593 if not frame.is_optimized_out():
1594 return frame
1595 return orig_frame
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001596 except ValueError:
1597 return None
1598
1599 @classmethod
1600 def get_selected_frame(cls):
1601 _gdbframe = gdb.selected_frame()
1602 if _gdbframe:
1603 return Frame(_gdbframe)
1604 return None
1605
1606 @classmethod
1607 def get_selected_python_frame(cls):
David Malcolm8d37ffa2012-06-27 14:15:34 -04001608 '''Try to obtain the Frame for the python-related code in the selected
1609 frame, or None'''
Victor Stinner610f5d72016-12-16 10:00:39 +01001610 try:
1611 frame = cls.get_selected_frame()
1612 except gdb.error:
1613 # No frame: Python didn't start yet
1614 return None
David Malcolm8d37ffa2012-06-27 14:15:34 -04001615
1616 while frame:
1617 if frame.is_python_frame():
1618 return frame
1619 frame = frame.older()
1620
1621 # Not found:
1622 return None
1623
1624 @classmethod
1625 def get_selected_bytecode_frame(cls):
1626 '''Try to obtain the Frame for the python bytecode interpreter in the
1627 selected GDB frame, or None'''
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001628 frame = cls.get_selected_frame()
1629
1630 while frame:
1631 if frame.is_evalframeex():
1632 return frame
1633 frame = frame.older()
1634
1635 # Not found:
1636 return None
1637
1638 def print_summary(self):
1639 if self.is_evalframeex():
1640 pyop = self.get_pyop()
1641 if pyop:
Victor Stinner0e5a41b2010-08-17 22:49:25 +00001642 line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1643 write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line))
Victor Stinnerd2084162011-12-19 13:42:24 +01001644 if not pyop.is_optimized_out():
1645 line = pyop.current_line()
1646 if line is not None:
1647 sys.stdout.write(' %s\n' % line.strip())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001648 else:
1649 sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index())
1650 else:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001651 info = self.is_other_python_frame()
1652 if info:
1653 sys.stdout.write('#%i %s\n' % (self.get_index(), info))
1654 else:
1655 sys.stdout.write('#%i\n' % self.get_index())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001656
Victor Stinnere670c882011-05-13 17:40:15 +02001657 def print_traceback(self):
1658 if self.is_evalframeex():
1659 pyop = self.get_pyop()
1660 if pyop:
1661 pyop.print_traceback()
Victor Stinnerd2084162011-12-19 13:42:24 +01001662 if not pyop.is_optimized_out():
1663 line = pyop.current_line()
1664 if line is not None:
1665 sys.stdout.write(' %s\n' % line.strip())
Victor Stinnere670c882011-05-13 17:40:15 +02001666 else:
1667 sys.stdout.write(' (unable to read python frame information)\n')
1668 else:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001669 info = self.is_other_python_frame()
1670 if info:
1671 sys.stdout.write(' %s\n' % info)
1672 else:
1673 sys.stdout.write(' (not a python frame)\n')
Victor Stinnere670c882011-05-13 17:40:15 +02001674
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001675class PyList(gdb.Command):
1676 '''List the current Python source code, if any
1677
1678 Use
1679 py-list START
1680 to list at a different line number within the python source.
1681
1682 Use
1683 py-list START, END
1684 to list a specific range of lines within the python source.
1685 '''
1686
1687 def __init__(self):
1688 gdb.Command.__init__ (self,
1689 "py-list",
1690 gdb.COMMAND_FILES,
1691 gdb.COMPLETE_NONE)
1692
1693
1694 def invoke(self, args, from_tty):
1695 import re
1696
1697 start = None
1698 end = None
1699
1700 m = re.match(r'\s*(\d+)\s*', args)
1701 if m:
1702 start = int(m.group(0))
1703 end = start + 10
1704
1705 m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args)
1706 if m:
1707 start, end = map(int, m.groups())
1708
David Malcolm8d37ffa2012-06-27 14:15:34 -04001709 # py-list requires an actual PyEval_EvalFrameEx frame:
1710 frame = Frame.get_selected_bytecode_frame()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001711 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001712 print('Unable to locate gdb frame for python bytecode interpreter')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001713 return
1714
1715 pyop = frame.get_pyop()
Victor Stinnerd2084162011-12-19 13:42:24 +01001716 if not pyop or pyop.is_optimized_out():
Antoine Pitroue50240c2013-11-23 17:40:36 +01001717 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001718 return
1719
1720 filename = pyop.filename()
1721 lineno = pyop.current_line_num()
1722
1723 if start is None:
1724 start = lineno - 5
1725 end = lineno + 5
1726
1727 if start<1:
1728 start = 1
1729
Victor Stinnerd57c5c82011-07-01 12:57:44 +02001730 try:
1731 f = open(os_fsencode(filename), 'r')
1732 except IOError as err:
1733 sys.stdout.write('Unable to open %s: %s\n'
1734 % (filename, err))
1735 return
1736 with f:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001737 all_lines = f.readlines()
1738 # start and end are 1-based, all_lines is 0-based;
1739 # so [start-1:end] as a python slice gives us [start, end] as a
1740 # closed interval
1741 for i, line in enumerate(all_lines[start-1:end]):
1742 linestr = str(i+start)
1743 # Highlight current line:
1744 if i + start == lineno:
1745 linestr = '>' + linestr
1746 sys.stdout.write('%4s %s' % (linestr, line))
1747
1748
1749# ...and register the command:
1750PyList()
1751
1752def move_in_stack(move_up):
1753 '''Move up or down the stack (for the py-up/py-down command)'''
1754 frame = Frame.get_selected_python_frame()
Victor Stinner610f5d72016-12-16 10:00:39 +01001755 if not frame:
1756 print('Unable to locate python frame')
1757 return
1758
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001759 while frame:
1760 if move_up:
1761 iter_frame = frame.older()
1762 else:
1763 iter_frame = frame.newer()
1764
1765 if not iter_frame:
1766 break
1767
David Malcolm8d37ffa2012-06-27 14:15:34 -04001768 if iter_frame.is_python_frame():
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001769 # Result:
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001770 if iter_frame.select():
1771 iter_frame.print_summary()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001772 return
1773
1774 frame = iter_frame
1775
1776 if move_up:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001777 print('Unable to find an older python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001778 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001779 print('Unable to find a newer python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001780
1781class PyUp(gdb.Command):
1782 'Select and print the python stack frame that called this one (if any)'
1783 def __init__(self):
1784 gdb.Command.__init__ (self,
1785 "py-up",
1786 gdb.COMMAND_STACK,
1787 gdb.COMPLETE_NONE)
1788
1789
1790 def invoke(self, args, from_tty):
1791 move_in_stack(move_up=True)
1792
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001793class PyDown(gdb.Command):
1794 'Select and print the python stack frame called by this one (if any)'
1795 def __init__(self):
1796 gdb.Command.__init__ (self,
1797 "py-down",
1798 gdb.COMMAND_STACK,
1799 gdb.COMPLETE_NONE)
1800
1801
1802 def invoke(self, args, from_tty):
1803 move_in_stack(move_up=False)
1804
Victor Stinner50eb60e2010-04-20 22:32:07 +00001805# Not all builds of gdb have gdb.Frame.select
1806if hasattr(gdb.Frame, 'select'):
1807 PyUp()
1808 PyDown()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001809
Victor Stinnere670c882011-05-13 17:40:15 +02001810class PyBacktraceFull(gdb.Command):
1811 'Display the current python frame and all the frames within its call stack (if any)'
1812 def __init__(self):
1813 gdb.Command.__init__ (self,
1814 "py-bt-full",
1815 gdb.COMMAND_STACK,
1816 gdb.COMPLETE_NONE)
1817
1818
1819 def invoke(self, args, from_tty):
1820 frame = Frame.get_selected_python_frame()
Victor Stinner610f5d72016-12-16 10:00:39 +01001821 if not frame:
1822 print('Unable to locate python frame')
1823 return
1824
Victor Stinnere670c882011-05-13 17:40:15 +02001825 while frame:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001826 if frame.is_python_frame():
Victor Stinnere670c882011-05-13 17:40:15 +02001827 frame.print_summary()
1828 frame = frame.older()
1829
1830PyBacktraceFull()
1831
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001832class PyBacktrace(gdb.Command):
1833 'Display the current python frame and all the frames within its call stack (if any)'
1834 def __init__(self):
1835 gdb.Command.__init__ (self,
1836 "py-bt",
1837 gdb.COMMAND_STACK,
1838 gdb.COMPLETE_NONE)
1839
1840
1841 def invoke(self, args, from_tty):
1842 frame = Frame.get_selected_python_frame()
Victor Stinner610f5d72016-12-16 10:00:39 +01001843 if not frame:
1844 print('Unable to locate python frame')
1845 return
1846
1847 sys.stdout.write('Traceback (most recent call first):\n')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001848 while frame:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001849 if frame.is_python_frame():
Victor Stinnere670c882011-05-13 17:40:15 +02001850 frame.print_traceback()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001851 frame = frame.older()
1852
1853PyBacktrace()
1854
1855class PyPrint(gdb.Command):
1856 'Look up the given python variable name, and print it'
1857 def __init__(self):
1858 gdb.Command.__init__ (self,
1859 "py-print",
1860 gdb.COMMAND_DATA,
1861 gdb.COMPLETE_NONE)
1862
1863
1864 def invoke(self, args, from_tty):
1865 name = str(args)
1866
1867 frame = Frame.get_selected_python_frame()
1868 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001869 print('Unable to locate python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001870 return
1871
1872 pyop_frame = frame.get_pyop()
1873 if not pyop_frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001874 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001875 return
1876
1877 pyop_var, scope = pyop_frame.get_var_by_name(name)
1878
1879 if pyop_var:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001880 print('%s %r = %s'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001881 % (scope,
1882 name,
1883 pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
1884 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001885 print('%r not found' % name)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001886
1887PyPrint()
1888
1889class PyLocals(gdb.Command):
1890 'Look up the given python variable name, and print it'
1891 def __init__(self):
1892 gdb.Command.__init__ (self,
1893 "py-locals",
1894 gdb.COMMAND_DATA,
1895 gdb.COMPLETE_NONE)
1896
1897
1898 def invoke(self, args, from_tty):
1899 name = str(args)
1900
1901 frame = Frame.get_selected_python_frame()
1902 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001903 print('Unable to locate python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001904 return
1905
1906 pyop_frame = frame.get_pyop()
1907 if not pyop_frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001908 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001909 return
1910
1911 for pyop_name, pyop_value in pyop_frame.iter_locals():
Antoine Pitroue50240c2013-11-23 17:40:36 +01001912 print('%s = %s'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001913 % (pyop_name.proxyval(set()),
1914 pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)))
1915
1916PyLocals()