blob: 75f1ccbd442d8d90616ed2e63148baaa5df8b604 [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
47from __future__ import print_function, with_statement
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,
365 }
366 if tp_name in name_map:
367 return name_map[tp_name]
368
369 if tp_flags & Py_TPFLAGS_HEAPTYPE:
370 return HeapTypeObjectPtr
371
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000372 if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
373 return PyLongObjectPtr
374 if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
375 return PyListObjectPtr
376 if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
377 return PyTupleObjectPtr
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000378 if tp_flags & Py_TPFLAGS_BYTES_SUBCLASS:
Victor Stinner67df3a42010-04-21 13:53:05 +0000379 return PyBytesObjectPtr
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000380 if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
381 return PyUnicodeObjectPtr
382 if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
383 return PyDictObjectPtr
384 if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
385 return PyBaseExceptionObjectPtr
386 #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
387 # return PyTypeObjectPtr
388
389 # Use the base class:
390 return cls
391
392 @classmethod
393 def from_pyobject_ptr(cls, gdbval):
394 '''
395 Try to locate the appropriate derived class dynamically, and cast
396 the pointer accordingly.
397 '''
398 try:
399 p = PyObjectPtr(gdbval)
400 cls = cls.subclass_from_type(p.type())
401 return cls(gdbval, cast_to=cls.get_gdb_type())
402 except RuntimeError:
403 # Handle any kind of error e.g. NULL ptrs by simply using the base
404 # class
405 pass
406 return cls(gdbval)
407
408 @classmethod
409 def get_gdb_type(cls):
410 return gdb.lookup_type(cls._typename).pointer()
411
412 def as_address(self):
413 return long(self._gdbval)
414
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000415class PyVarObjectPtr(PyObjectPtr):
416 _typename = 'PyVarObject'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000417
418class ProxyAlreadyVisited(object):
419 '''
420 Placeholder proxy to use when protecting against infinite recursion due to
421 loops in the object graph.
422
423 Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave
424 '''
425 def __init__(self, rep):
426 self._rep = rep
427
428 def __repr__(self):
429 return self._rep
430
431
432def _write_instance_repr(out, visited, name, pyop_attrdict, address):
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100433 '''Shared code for use by all classes:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000434 write a representation to file-like object "out"'''
435 out.write('<')
436 out.write(name)
437
438 # Write dictionary of instance attributes:
439 if isinstance(pyop_attrdict, PyDictObjectPtr):
440 out.write('(')
441 first = True
442 for pyop_arg, pyop_val in pyop_attrdict.iteritems():
443 if not first:
444 out.write(', ')
445 first = False
446 out.write(pyop_arg.proxyval(visited))
447 out.write('=')
448 pyop_val.write_repr(out, visited)
449 out.write(')')
450 out.write(' at remote 0x%x>' % address)
451
452
453class InstanceProxy(object):
454
455 def __init__(self, cl_name, attrdict, address):
456 self.cl_name = cl_name
457 self.attrdict = attrdict
458 self.address = address
459
460 def __repr__(self):
461 if isinstance(self.attrdict, dict):
462 kwargs = ', '.join(["%s=%r" % (arg, val)
463 for arg, val in self.attrdict.iteritems()])
464 return '<%s(%s) at remote 0x%x>' % (self.cl_name,
465 kwargs, self.address)
466 else:
467 return '<%s at remote 0x%x>' % (self.cl_name,
468 self.address)
469
470def _PyObject_VAR_SIZE(typeobj, nitems):
Victor Stinnerd2084162011-12-19 13:42:24 +0100471 if _PyObject_VAR_SIZE._type_size_t is None:
472 _PyObject_VAR_SIZE._type_size_t = gdb.lookup_type('size_t')
473
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000474 return ( ( typeobj.field('tp_basicsize') +
475 nitems * typeobj.field('tp_itemsize') +
Victor Stinner4e75ca82016-04-20 18:07:21 +0200476 (_sizeof_void_p() - 1)
477 ) & ~(_sizeof_void_p() - 1)
Victor Stinnerd2084162011-12-19 13:42:24 +0100478 ).cast(_PyObject_VAR_SIZE._type_size_t)
479_PyObject_VAR_SIZE._type_size_t = None
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000480
481class HeapTypeObjectPtr(PyObjectPtr):
482 _typename = 'PyObject'
483
484 def get_attr_dict(self):
485 '''
486 Get the PyDictObject ptr representing the attribute dictionary
487 (or None if there's a problem)
488 '''
489 try:
490 typeobj = self.type()
491 dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
492 if dictoffset != 0:
493 if dictoffset < 0:
494 type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
495 tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
496 if tsize < 0:
497 tsize = -tsize
498 size = _PyObject_VAR_SIZE(typeobj, tsize)
499 dictoffset += size
500 assert dictoffset > 0
Victor Stinner4e75ca82016-04-20 18:07:21 +0200501 assert dictoffset % _sizeof_void_p() == 0
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000502
Victor Stinner4e75ca82016-04-20 18:07:21 +0200503 dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000504 PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
505 dictptr = dictptr.cast(PyObjectPtrPtr)
506 return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
507 except RuntimeError:
508 # Corrupt data somewhere; fail safe
509 pass
510
511 # Not found, or some kind of error:
512 return None
513
514 def proxyval(self, visited):
515 '''
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100516 Support for classes.
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000517
518 Currently we just locate the dictionary using a transliteration to
519 python of _PyObject_GetDictPtr, ignoring descriptors
520 '''
521 # Guard against infinite loops:
522 if self.as_address() in visited:
523 return ProxyAlreadyVisited('<...>')
524 visited.add(self.as_address())
525
526 pyop_attr_dict = self.get_attr_dict()
527 if pyop_attr_dict:
528 attr_dict = pyop_attr_dict.proxyval(visited)
529 else:
530 attr_dict = {}
531 tp_name = self.safe_tp_name()
532
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100533 # Class:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000534 return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
535
536 def write_repr(self, out, visited):
537 # Guard against infinite loops:
538 if self.as_address() in visited:
539 out.write('<...>')
540 return
541 visited.add(self.as_address())
542
543 pyop_attrdict = self.get_attr_dict()
544 _write_instance_repr(out, visited,
545 self.safe_tp_name(), pyop_attrdict, self.as_address())
546
547class ProxyException(Exception):
548 def __init__(self, tp_name, args):
549 self.tp_name = tp_name
550 self.args = args
551
552 def __repr__(self):
553 return '%s%r' % (self.tp_name, self.args)
554
555class PyBaseExceptionObjectPtr(PyObjectPtr):
556 """
557 Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception
558 within the process being debugged.
559 """
560 _typename = 'PyBaseExceptionObject'
561
562 def proxyval(self, visited):
563 # Guard against infinite loops:
564 if self.as_address() in visited:
565 return ProxyAlreadyVisited('(...)')
566 visited.add(self.as_address())
567 arg_proxy = self.pyop_field('args').proxyval(visited)
568 return ProxyException(self.safe_tp_name(),
569 arg_proxy)
570
571 def write_repr(self, out, visited):
572 # Guard against infinite loops:
573 if self.as_address() in visited:
574 out.write('(...)')
575 return
576 visited.add(self.as_address())
577
578 out.write(self.safe_tp_name())
579 self.write_field_repr('args', out, visited)
580
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000581class PyClassObjectPtr(PyObjectPtr):
582 """
583 Class wrapping a gdb.Value that's a PyClassObject* i.e. a <classobj>
584 instance within the process being debugged.
585 """
586 _typename = 'PyClassObject'
587
588
589class BuiltInFunctionProxy(object):
590 def __init__(self, ml_name):
591 self.ml_name = ml_name
592
593 def __repr__(self):
594 return "<built-in function %s>" % self.ml_name
595
596class BuiltInMethodProxy(object):
597 def __init__(self, ml_name, pyop_m_self):
598 self.ml_name = ml_name
599 self.pyop_m_self = pyop_m_self
600
601 def __repr__(self):
602 return ('<built-in method %s of %s object at remote 0x%x>'
603 % (self.ml_name,
604 self.pyop_m_self.safe_tp_name(),
605 self.pyop_m_self.as_address())
606 )
607
608class PyCFunctionObjectPtr(PyObjectPtr):
609 """
610 Class wrapping a gdb.Value that's a PyCFunctionObject*
611 (see Include/methodobject.h and Objects/methodobject.c)
612 """
613 _typename = 'PyCFunctionObject'
614
615 def proxyval(self, visited):
616 m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
617 ml_name = m_ml['ml_name'].string()
618
619 pyop_m_self = self.pyop_field('m_self')
620 if pyop_m_self.is_null():
621 return BuiltInFunctionProxy(ml_name)
622 else:
623 return BuiltInMethodProxy(ml_name, pyop_m_self)
624
625
626class PyCodeObjectPtr(PyObjectPtr):
627 """
628 Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
629 within the process being debugged.
630 """
631 _typename = 'PyCodeObject'
632
633 def addr2line(self, addrq):
634 '''
635 Get the line number for a given bytecode offset
636
637 Analogous to PyCode_Addr2Line; translated from pseudocode in
638 Objects/lnotab_notes.txt
639 '''
640 co_lnotab = self.pyop_field('co_lnotab').proxyval(set())
641
642 # Initialize lineno to co_firstlineno as per PyCode_Addr2Line
643 # not 0, as lnotab_notes.txt has it:
644 lineno = int_from_int(self.field('co_firstlineno'))
645
646 addr = 0
647 for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
648 addr += ord(addr_incr)
649 if addr > addrq:
650 return lineno
651 lineno += ord(line_incr)
652 return lineno
653
654
655class PyDictObjectPtr(PyObjectPtr):
656 """
657 Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
658 within the process being debugged.
659 """
660 _typename = 'PyDictObject'
661
662 def iteritems(self):
663 '''
664 Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
Ezio Melotti7c4a7e62013-08-26 01:32:56 +0300665 analogous to dict.iteritems()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000666 '''
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400667 keys = self.field('ma_keys')
668 values = self.field('ma_values')
669 for i in safe_range(keys['dk_size']):
670 ep = keys['dk_entries'].address + i
671 if long(values):
672 pyop_value = PyObjectPtr.from_pyobject_ptr(values[i])
673 else:
674 pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000675 if not pyop_value.is_null():
676 pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
677 yield (pyop_key, pyop_value)
678
679 def proxyval(self, visited):
680 # Guard against infinite loops:
681 if self.as_address() in visited:
682 return ProxyAlreadyVisited('{...}')
683 visited.add(self.as_address())
684
685 result = {}
686 for pyop_key, pyop_value in self.iteritems():
687 proxy_key = pyop_key.proxyval(visited)
688 proxy_value = pyop_value.proxyval(visited)
689 result[proxy_key] = proxy_value
690 return result
691
692 def write_repr(self, out, visited):
693 # Guard against infinite loops:
694 if self.as_address() in visited:
695 out.write('{...}')
696 return
697 visited.add(self.as_address())
698
699 out.write('{')
700 first = True
701 for pyop_key, pyop_value in self.iteritems():
702 if not first:
703 out.write(', ')
704 first = False
705 pyop_key.write_repr(out, visited)
706 out.write(': ')
707 pyop_value.write_repr(out, visited)
708 out.write('}')
709
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000710class PyListObjectPtr(PyObjectPtr):
711 _typename = 'PyListObject'
712
713 def __getitem__(self, i):
714 # Get the gdb.Value for the (PyObject*) with the given index:
715 field_ob_item = self.field('ob_item')
716 return field_ob_item[i]
717
718 def proxyval(self, visited):
719 # Guard against infinite loops:
720 if self.as_address() in visited:
721 return ProxyAlreadyVisited('[...]')
722 visited.add(self.as_address())
723
724 result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
725 for i in safe_range(int_from_int(self.field('ob_size')))]
726 return result
727
728 def write_repr(self, out, visited):
729 # Guard against infinite loops:
730 if self.as_address() in visited:
731 out.write('[...]')
732 return
733 visited.add(self.as_address())
734
735 out.write('[')
736 for i in safe_range(int_from_int(self.field('ob_size'))):
737 if i > 0:
738 out.write(', ')
739 element = PyObjectPtr.from_pyobject_ptr(self[i])
740 element.write_repr(out, visited)
741 out.write(']')
742
743class PyLongObjectPtr(PyObjectPtr):
744 _typename = 'PyLongObject'
745
746 def proxyval(self, visited):
747 '''
748 Python's Include/longobjrep.h has this declaration:
749 struct _longobject {
750 PyObject_VAR_HEAD
751 digit ob_digit[1];
752 };
753
754 with this description:
755 The absolute value of a number is equal to
756 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
757 Negative numbers are represented with ob_size < 0;
758 zero is represented by ob_size == 0.
759
760 where SHIFT can be either:
761 #define PyLong_SHIFT 30
762 #define PyLong_SHIFT 15
763 '''
764 ob_size = long(self.field('ob_size'))
765 if ob_size == 0:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100766 return 0
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000767
768 ob_digit = self.field('ob_digit')
769
770 if gdb.lookup_type('digit').sizeof == 2:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100771 SHIFT = 15
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000772 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +0100773 SHIFT = 30
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000774
775 digits = [long(ob_digit[i]) * 2**(SHIFT*i)
776 for i in safe_range(abs(ob_size))]
777 result = sum(digits)
778 if ob_size < 0:
779 result = -result
780 return result
781
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000782 def write_repr(self, out, visited):
783 # Write this out as a Python 3 int literal, i.e. without the "L" suffix
784 proxy = self.proxyval(visited)
785 out.write("%s" % proxy)
786
787
788class PyBoolObjectPtr(PyLongObjectPtr):
789 """
790 Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
791 <bool> instances (Py_True/Py_False) within the process being debugged.
792 """
793 def proxyval(self, visited):
794 if PyLongObjectPtr.proxyval(self, visited):
795 return True
796 else:
797 return False
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000798
799class PyNoneStructPtr(PyObjectPtr):
800 """
801 Class wrapping a gdb.Value that's a PyObject* pointing to the
802 singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type
803 """
804 _typename = 'PyObject'
805
806 def proxyval(self, visited):
807 return None
808
809
810class PyFrameObjectPtr(PyObjectPtr):
811 _typename = 'PyFrameObject'
812
Victor Stinnerd2084162011-12-19 13:42:24 +0100813 def __init__(self, gdbval, cast_to=None):
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000814 PyObjectPtr.__init__(self, gdbval, cast_to)
815
816 if not self.is_optimized_out():
817 self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
818 self.co_name = self.co.pyop_field('co_name')
819 self.co_filename = self.co.pyop_field('co_filename')
820
821 self.f_lineno = int_from_int(self.field('f_lineno'))
822 self.f_lasti = int_from_int(self.field('f_lasti'))
823 self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
824 self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))
825
826 def iter_locals(self):
827 '''
828 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
829 the local variables of this frame
830 '''
831 if self.is_optimized_out():
832 return
833
834 f_localsplus = self.field('f_localsplus')
835 for i in safe_range(self.co_nlocals):
836 pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
837 if not pyop_value.is_null():
838 pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
839 yield (pyop_name, pyop_value)
840
841 def iter_globals(self):
842 '''
843 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
844 the global variables of this frame
845 '''
846 if self.is_optimized_out():
Victor Stinnerd2084162011-12-19 13:42:24 +0100847 return ()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000848
849 pyop_globals = self.pyop_field('f_globals')
850 return pyop_globals.iteritems()
851
852 def iter_builtins(self):
853 '''
854 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
855 the builtin variables
856 '''
857 if self.is_optimized_out():
Victor Stinnerd2084162011-12-19 13:42:24 +0100858 return ()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000859
860 pyop_builtins = self.pyop_field('f_builtins')
861 return pyop_builtins.iteritems()
862
863 def get_var_by_name(self, name):
864 '''
865 Look for the named local variable, returning a (PyObjectPtr, scope) pair
866 where scope is a string 'local', 'global', 'builtin'
867
868 If not found, return (None, None)
869 '''
870 for pyop_name, pyop_value in self.iter_locals():
871 if name == pyop_name.proxyval(set()):
872 return pyop_value, 'local'
873 for pyop_name, pyop_value in self.iter_globals():
874 if name == pyop_name.proxyval(set()):
875 return pyop_value, 'global'
876 for pyop_name, pyop_value in self.iter_builtins():
877 if name == pyop_name.proxyval(set()):
878 return pyop_value, 'builtin'
879 return None, None
880
881 def filename(self):
882 '''Get the path of the current Python source file, as a string'''
883 if self.is_optimized_out():
884 return '(frame information optimized out)'
885 return self.co_filename.proxyval(set())
886
887 def current_line_num(self):
888 '''Get current line number as an integer (1-based)
889
890 Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
891
892 See Objects/lnotab_notes.txt
893 '''
894 if self.is_optimized_out():
895 return None
896 f_trace = self.field('f_trace')
897 if long(f_trace) != 0:
898 # we have a non-NULL f_trace:
899 return self.f_lineno
900 else:
901 #try:
902 return self.co.addr2line(self.f_lasti)
903 #except ValueError:
904 # return self.f_lineno
905
906 def current_line(self):
907 '''Get the text of the current source line as a string, with a trailing
908 newline character'''
909 if self.is_optimized_out():
910 return '(frame information optimized out)'
Victor Stinner6ffbee72010-10-17 19:35:30 +0000911 filename = self.filename()
Victor Stinnerd57c5c82011-07-01 12:57:44 +0200912 try:
913 f = open(os_fsencode(filename), 'r')
914 except IOError:
915 return None
916 with f:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000917 all_lines = f.readlines()
918 # Convert from 1-based current_line_num to 0-based list offset:
919 return all_lines[self.current_line_num()-1]
920
921 def write_repr(self, out, visited):
922 if self.is_optimized_out():
923 out.write('(frame information optimized out)')
924 return
925 out.write('Frame 0x%x, for file %s, line %i, in %s ('
926 % (self.as_address(),
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000927 self.co_filename.proxyval(visited),
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000928 self.current_line_num(),
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000929 self.co_name.proxyval(visited)))
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000930 first = True
931 for pyop_name, pyop_value in self.iter_locals():
932 if not first:
933 out.write(', ')
934 first = False
935
936 out.write(pyop_name.proxyval(visited))
937 out.write('=')
938 pyop_value.write_repr(out, visited)
939
940 out.write(')')
941
Victor Stinnere670c882011-05-13 17:40:15 +0200942 def print_traceback(self):
943 if self.is_optimized_out():
944 sys.stdout.write(' (frame information optimized out)\n')
Victor Stinnerd2084162011-12-19 13:42:24 +0100945 return
Victor Stinnere670c882011-05-13 17:40:15 +0200946 visited = set()
947 sys.stdout.write(' File "%s", line %i, in %s\n'
948 % (self.co_filename.proxyval(visited),
949 self.current_line_num(),
950 self.co_name.proxyval(visited)))
951
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000952class PySetObjectPtr(PyObjectPtr):
953 _typename = 'PySetObject'
954
Antoine Pitrou9d952542013-08-24 21:07:07 +0200955 @classmethod
956 def _dummy_key(self):
957 return gdb.lookup_global_symbol('_PySet_Dummy').value()
958
959 def __iter__(self):
960 dummy_ptr = self._dummy_key()
961 table = self.field('table')
962 for i in safe_range(self.field('mask') + 1):
963 setentry = table[i]
964 key = setentry['key']
965 if key != 0 and key != dummy_ptr:
966 yield PyObjectPtr.from_pyobject_ptr(key)
967
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000968 def proxyval(self, visited):
969 # Guard against infinite loops:
970 if self.as_address() in visited:
971 return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
972 visited.add(self.as_address())
973
Antoine Pitrou9d952542013-08-24 21:07:07 +0200974 members = (key.proxyval(visited) for key in self)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000975 if self.safe_tp_name() == 'frozenset':
976 return frozenset(members)
977 else:
978 return set(members)
979
980 def write_repr(self, out, visited):
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000981 # Emulate Python 3's set_repr
982 tp_name = self.safe_tp_name()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +0000983
984 # Guard against infinite loops:
985 if self.as_address() in visited:
986 out.write('(...)')
987 return
988 visited.add(self.as_address())
989
Martin v. Löwis5ae68102010-04-21 22:38:42 +0000990 # Python 3's set_repr special-cases the empty set:
991 if not self.field('used'):
992 out.write(tp_name)
993 out.write('()')
994 return
995
996 # Python 3 uses {} for set literals:
997 if tp_name != 'set':
998 out.write(tp_name)
999 out.write('(')
1000
1001 out.write('{')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001002 first = True
Antoine Pitrou9d952542013-08-24 21:07:07 +02001003 for key in self:
1004 if not first:
1005 out.write(', ')
1006 first = False
1007 key.write_repr(out, visited)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001008 out.write('}')
1009
1010 if tp_name != 'set':
1011 out.write(')')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001012
1013
Victor Stinner67df3a42010-04-21 13:53:05 +00001014class PyBytesObjectPtr(PyObjectPtr):
1015 _typename = 'PyBytesObject'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001016
1017 def __str__(self):
1018 field_ob_size = self.field('ob_size')
1019 field_ob_sval = self.field('ob_sval')
Victor Stinner4e75ca82016-04-20 18:07:21 +02001020 char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001021 return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
1022
1023 def proxyval(self, visited):
1024 return str(self)
1025
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001026 def write_repr(self, out, visited):
1027 # Write this out as a Python 3 bytes literal, i.e. with a "b" prefix
1028
1029 # Get a PyStringObject* within the Python 2 gdb process:
1030 proxy = self.proxyval(visited)
1031
1032 # Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr
1033 # to Python 2 code:
1034 quote = "'"
1035 if "'" in proxy and not '"' in proxy:
1036 quote = '"'
1037 out.write('b')
1038 out.write(quote)
1039 for byte in proxy:
1040 if byte == quote or byte == '\\':
1041 out.write('\\')
1042 out.write(byte)
1043 elif byte == '\t':
1044 out.write('\\t')
1045 elif byte == '\n':
1046 out.write('\\n')
1047 elif byte == '\r':
1048 out.write('\\r')
1049 elif byte < ' ' or ord(byte) >= 0x7f:
1050 out.write('\\x')
1051 out.write(hexdigits[(ord(byte) & 0xf0) >> 4])
1052 out.write(hexdigits[ord(byte) & 0xf])
1053 else:
1054 out.write(byte)
1055 out.write(quote)
1056
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001057class PyTupleObjectPtr(PyObjectPtr):
1058 _typename = 'PyTupleObject'
1059
1060 def __getitem__(self, i):
1061 # Get the gdb.Value for the (PyObject*) with the given index:
1062 field_ob_item = self.field('ob_item')
1063 return field_ob_item[i]
1064
1065 def proxyval(self, visited):
1066 # Guard against infinite loops:
1067 if self.as_address() in visited:
1068 return ProxyAlreadyVisited('(...)')
1069 visited.add(self.as_address())
1070
1071 result = tuple([PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
1072 for i in safe_range(int_from_int(self.field('ob_size')))])
1073 return result
1074
1075 def write_repr(self, out, visited):
1076 # Guard against infinite loops:
1077 if self.as_address() in visited:
1078 out.write('(...)')
1079 return
1080 visited.add(self.as_address())
1081
1082 out.write('(')
1083 for i in safe_range(int_from_int(self.field('ob_size'))):
1084 if i > 0:
1085 out.write(', ')
1086 element = PyObjectPtr.from_pyobject_ptr(self[i])
1087 element.write_repr(out, visited)
1088 if self.field('ob_size') == 1:
1089 out.write(',)')
1090 else:
1091 out.write(')')
1092
1093class PyTypeObjectPtr(PyObjectPtr):
1094 _typename = 'PyTypeObject'
1095
1096
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001097def _unichr_is_printable(char):
1098 # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
1099 if char == u" ":
1100 return True
1101 import unicodedata
Antoine Pitroub41e1282010-09-08 20:57:48 +00001102 return unicodedata.category(char) not in ("C", "Z")
1103
1104if sys.maxunicode >= 0x10000:
1105 _unichr = unichr
1106else:
1107 # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
1108 def _unichr(x):
1109 if x < 0x10000:
1110 return unichr(x)
1111 x -= 0x10000
1112 ch1 = 0xD800 | (x >> 10)
1113 ch2 = 0xDC00 | (x & 0x3FF)
1114 return unichr(ch1) + unichr(ch2)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001115
1116
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001117class PyUnicodeObjectPtr(PyObjectPtr):
1118 _typename = 'PyUnicodeObject'
1119
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001120 def char_width(self):
1121 _type_Py_UNICODE = gdb.lookup_type('Py_UNICODE')
1122 return _type_Py_UNICODE.sizeof
1123
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001124 def proxyval(self, visited):
Victor Stinner0c4fbff2011-12-08 00:08:22 +01001125 global _is_pep393
1126 if _is_pep393 is None:
1127 fields = gdb.lookup_type('PyUnicodeObject').target().fields()
1128 _is_pep393 = 'data' in [f.name for f in fields]
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001129 if _is_pep393:
1130 # Python 3.3 and newer
1131 may_have_surrogates = False
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001132 compact = self.field('_base')
1133 ascii = compact['_base']
1134 state = ascii['state']
Victor Stinnera3b334d2011-10-03 13:53:37 +02001135 is_compact_ascii = (int(state['ascii']) and int(state['compact']))
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001136 if not int(state['ready']):
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001137 # string is not ready
Victor Stinnerf16a3502011-11-04 22:34:01 +01001138 field_length = long(compact['wstr_length'])
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001139 may_have_surrogates = True
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001140 field_str = ascii['wstr']
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001141 else:
Victor Stinnerf16a3502011-11-04 22:34:01 +01001142 field_length = long(ascii['length'])
Victor Stinnera3b334d2011-10-03 13:53:37 +02001143 if is_compact_ascii:
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001144 field_str = ascii.address + 1
1145 elif int(state['compact']):
1146 field_str = compact.address + 1
1147 else:
1148 field_str = self.field('data')['any']
1149 repr_kind = int(state['kind'])
1150 if repr_kind == 1:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001151 field_str = field_str.cast(_type_unsigned_char_ptr())
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001152 elif repr_kind == 2:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001153 field_str = field_str.cast(_type_unsigned_short_ptr())
Antoine Pitrou3c0c5f22011-10-08 19:33:24 +02001154 elif repr_kind == 4:
Victor Stinner4e75ca82016-04-20 18:07:21 +02001155 field_str = field_str.cast(_type_unsigned_int_ptr())
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001156 else:
1157 # Python 3.2 and earlier
Martin v. Löwis24fa9832011-09-28 08:35:25 +02001158 field_length = long(self.field('length'))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001159 field_str = self.field('str')
1160 may_have_surrogates = self.char_width() == 2
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001161
1162 # Gather a list of ints from the Py_UNICODE array; these are either
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001163 # UCS-1, UCS-2 or UCS-4 code points:
1164 if not may_have_surrogates:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001165 Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
1166 else:
1167 # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
1168 # inferior process: we must join surrogate pairs.
1169 Py_UNICODEs = []
1170 i = 0
Antoine Pitroub1856d72010-09-08 21:07:40 +00001171 limit = safety_limit(field_length)
1172 while i < limit:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001173 ucs = int(field_str[i])
1174 i += 1
1175 if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
1176 Py_UNICODEs.append(ucs)
1177 continue
1178 # This could be a surrogate pair.
1179 ucs2 = int(field_str[i])
1180 if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
1181 continue
1182 code = (ucs & 0x03FF) << 10
1183 code |= ucs2 & 0x03FF
1184 code += 0x00010000
1185 Py_UNICODEs.append(code)
1186 i += 1
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001187
1188 # Convert the int code points to unicode characters, and generate a
Antoine Pitroub41e1282010-09-08 20:57:48 +00001189 # local unicode instance.
1190 # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
Victor Stinnerd8a5cc92013-04-11 21:37:45 +02001191 result = u''.join([
1192 (_unichr(ucs) if ucs <= 0x10ffff else '\ufffd')
1193 for ucs in Py_UNICODEs])
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001194 return result
1195
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001196 def write_repr(self, out, visited):
1197 # Write this out as a Python 3 str literal, i.e. without a "u" prefix
1198
1199 # Get a PyUnicodeObject* within the Python 2 gdb process:
1200 proxy = self.proxyval(visited)
1201
1202 # Transliteration of Python 3's Object/unicodeobject.c:unicode_repr
1203 # to Python 2:
1204 if "'" in proxy and '"' not in proxy:
1205 quote = '"'
1206 else:
1207 quote = "'"
1208 out.write(quote)
1209
1210 i = 0
1211 while i < len(proxy):
1212 ch = proxy[i]
1213 i += 1
1214
1215 # Escape quotes and backslashes
1216 if ch == quote or ch == '\\':
1217 out.write('\\')
1218 out.write(ch)
1219
1220 # Map special whitespace to '\t', \n', '\r'
1221 elif ch == '\t':
1222 out.write('\\t')
1223 elif ch == '\n':
1224 out.write('\\n')
1225 elif ch == '\r':
1226 out.write('\\r')
1227
1228 # Map non-printable US ASCII to '\xhh' */
1229 elif ch < ' ' or ch == 0x7F:
1230 out.write('\\x')
1231 out.write(hexdigits[(ord(ch) >> 4) & 0x000F])
1232 out.write(hexdigits[ord(ch) & 0x000F])
1233
1234 # Copy ASCII characters as-is
1235 elif ord(ch) < 0x7F:
1236 out.write(ch)
1237
1238 # Non-ASCII characters
1239 else:
Victor Stinner150016f2010-05-19 23:04:56 +00001240 ucs = ch
Antoine Pitroub41e1282010-09-08 20:57:48 +00001241 ch2 = None
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001242 if sys.maxunicode < 0x10000:
Antoine Pitroub41e1282010-09-08 20:57:48 +00001243 # If sizeof(Py_UNICODE) is 2 here (in gdb), join
1244 # surrogate pairs before calling _unichr_is_printable.
Victor Stinner150016f2010-05-19 23:04:56 +00001245 if (i < len(proxy)
1246 and 0xD800 <= ord(ch) < 0xDC00 \
1247 and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001248 ch2 = proxy[i]
Antoine Pitroub41e1282010-09-08 20:57:48 +00001249 ucs = ch + ch2
Victor Stinner150016f2010-05-19 23:04:56 +00001250 i += 1
Victor Stinner150016f2010-05-19 23:04:56 +00001251
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001252 # Unfortuately, Python 2's unicode type doesn't seem
1253 # to expose the "isprintable" method
Victor Stinner150016f2010-05-19 23:04:56 +00001254 printable = _unichr_is_printable(ucs)
1255 if printable:
1256 try:
1257 ucs.encode(ENCODING)
1258 except UnicodeEncodeError:
1259 printable = False
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001260
1261 # Map Unicode whitespace and control characters
1262 # (categories Z* and C* except ASCII space)
Victor Stinner150016f2010-05-19 23:04:56 +00001263 if not printable:
Antoine Pitrou7c9cf012010-09-08 21:57:37 +00001264 if ch2 is not None:
1265 # Match Python 3's representation of non-printable
1266 # wide characters.
1267 code = (ord(ch) & 0x03FF) << 10
1268 code |= ord(ch2) & 0x03FF
1269 code += 0x00010000
1270 else:
1271 code = ord(ucs)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001272
1273 # Map 8-bit characters to '\\xhh'
Victor Stinner150016f2010-05-19 23:04:56 +00001274 if code <= 0xff:
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001275 out.write('\\x')
Victor Stinner150016f2010-05-19 23:04:56 +00001276 out.write(hexdigits[(code >> 4) & 0x000F])
1277 out.write(hexdigits[code & 0x000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001278 # Map 21-bit characters to '\U00xxxxxx'
Victor Stinner150016f2010-05-19 23:04:56 +00001279 elif code >= 0x10000:
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001280 out.write('\\U')
Victor Stinner150016f2010-05-19 23:04:56 +00001281 out.write(hexdigits[(code >> 28) & 0x0000000F])
1282 out.write(hexdigits[(code >> 24) & 0x0000000F])
1283 out.write(hexdigits[(code >> 20) & 0x0000000F])
1284 out.write(hexdigits[(code >> 16) & 0x0000000F])
1285 out.write(hexdigits[(code >> 12) & 0x0000000F])
1286 out.write(hexdigits[(code >> 8) & 0x0000000F])
1287 out.write(hexdigits[(code >> 4) & 0x0000000F])
1288 out.write(hexdigits[code & 0x0000000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001289 # Map 16-bit characters to '\uxxxx'
1290 else:
1291 out.write('\\u')
Victor Stinner150016f2010-05-19 23:04:56 +00001292 out.write(hexdigits[(code >> 12) & 0x000F])
1293 out.write(hexdigits[(code >> 8) & 0x000F])
1294 out.write(hexdigits[(code >> 4) & 0x000F])
1295 out.write(hexdigits[code & 0x000F])
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001296 else:
1297 # Copy characters as-is
1298 out.write(ch)
Antoine Pitroub41e1282010-09-08 20:57:48 +00001299 if ch2 is not None:
Victor Stinner150016f2010-05-19 23:04:56 +00001300 out.write(ch2)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001301
1302 out.write(quote)
1303
1304
1305
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001306
1307def int_from_int(gdbval):
1308 return int(str(gdbval))
1309
1310
1311def stringify(val):
1312 # TODO: repr() puts everything on one line; pformat can be nicer, but
1313 # can lead to v.long results; this function isolates the choice
1314 if True:
1315 return repr(val)
1316 else:
1317 from pprint import pformat
1318 return pformat(val)
1319
1320
1321class PyObjectPtrPrinter:
1322 "Prints a (PyObject*)"
1323
1324 def __init__ (self, gdbval):
1325 self.gdbval = gdbval
1326
1327 def to_string (self):
1328 pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval)
1329 if True:
1330 return pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1331 else:
1332 # Generate full proxy value then stringify it.
1333 # Doing so could be expensive
1334 proxyval = pyop.proxyval(set())
1335 return stringify(proxyval)
1336
1337def pretty_printer_lookup(gdbval):
1338 type = gdbval.type.unqualified()
1339 if type.code == gdb.TYPE_CODE_PTR:
1340 type = type.target().unqualified()
1341 t = str(type)
Martin v. Löwis5ae68102010-04-21 22:38:42 +00001342 if t in ("PyObject", "PyFrameObject", "PyUnicodeObject"):
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001343 return PyObjectPtrPrinter(gdbval)
1344
1345"""
1346During development, I've been manually invoking the code in this way:
1347(gdb) python
1348
1349import sys
1350sys.path.append('/home/david/coding/python-gdb')
1351import libpython
1352end
1353
1354then reloading it after each edit like this:
1355(gdb) python reload(libpython)
1356
1357The following code should ensure that the prettyprinter is registered
1358if the code is autoloaded by gdb when visiting libpython.so, provided
1359that this python file is installed to the same path as the library (or its
1360.debug file) plus a "-gdb.py" suffix, e.g:
1361 /usr/lib/libpython2.6.so.1.0-gdb.py
1362 /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
1363"""
1364def register (obj):
Benjamin Petersonb29614e2012-10-09 11:16:03 -04001365 if obj is None:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001366 obj = gdb
1367
1368 # Wire up the pretty-printer
1369 obj.pretty_printers.append(pretty_printer_lookup)
1370
1371register (gdb.current_objfile ())
1372
1373
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001374
1375# Unfortunately, the exact API exposed by the gdb module varies somewhat
1376# from build to build
1377# See http://bugs.python.org/issue8279?#msg102276
1378
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001379class Frame(object):
1380 '''
1381 Wrapper for gdb.Frame, adding various methods
1382 '''
1383 def __init__(self, gdbframe):
1384 self._gdbframe = gdbframe
1385
1386 def older(self):
1387 older = self._gdbframe.older()
1388 if older:
1389 return Frame(older)
1390 else:
1391 return None
1392
1393 def newer(self):
1394 newer = self._gdbframe.newer()
1395 if newer:
1396 return Frame(newer)
1397 else:
1398 return None
1399
1400 def select(self):
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001401 '''If supported, select this frame and return True; return False if unsupported
1402
1403 Not all builds have a gdb.Frame.select method; seems to be present on Fedora 12
1404 onwards, but absent on Ubuntu buildbot'''
1405 if not hasattr(self._gdbframe, 'select'):
1406 print ('Unable to select frame: '
1407 'this build of gdb does not expose a gdb.Frame.select method')
1408 return False
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001409 self._gdbframe.select()
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001410 return True
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001411
1412 def get_index(self):
1413 '''Calculate index of frame, starting at 0 for the newest frame within
1414 this thread'''
1415 index = 0
1416 # Go down until you reach the newest frame:
1417 iter_frame = self
1418 while iter_frame.newer():
1419 index += 1
1420 iter_frame = iter_frame.newer()
1421 return index
1422
David Malcolm8d37ffa2012-06-27 14:15:34 -04001423 # We divide frames into:
1424 # - "python frames":
1425 # - "bytecode frames" i.e. PyEval_EvalFrameEx
1426 # - "other python frames": things that are of interest from a python
1427 # POV, but aren't bytecode (e.g. GC, GIL)
1428 # - everything else
1429
1430 def is_python_frame(self):
1431 '''Is this a PyEval_EvalFrameEx frame, or some other important
1432 frame? (see is_other_python_frame for what "important" means in this
1433 context)'''
1434 if self.is_evalframeex():
1435 return True
1436 if self.is_other_python_frame():
1437 return True
1438 return False
1439
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001440 def is_evalframeex(self):
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001441 '''Is this a PyEval_EvalFrameEx frame?'''
Victor Stinner50eb60e2010-04-20 22:32:07 +00001442 if self._gdbframe.name() == 'PyEval_EvalFrameEx':
1443 '''
1444 I believe we also need to filter on the inline
1445 struct frame_id.inline_depth, only regarding frames with
1446 an inline depth of 0 as actually being this function
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001447
Victor Stinner50eb60e2010-04-20 22:32:07 +00001448 So we reject those with type gdb.INLINE_FRAME
1449 '''
1450 if self._gdbframe.type() == gdb.NORMAL_FRAME:
1451 # We have a PyEval_EvalFrameEx frame:
1452 return True
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001453
1454 return False
1455
David Malcolm8d37ffa2012-06-27 14:15:34 -04001456 def is_other_python_frame(self):
1457 '''Is this frame worth displaying in python backtraces?
1458 Examples:
1459 - waiting on the GIL
1460 - garbage-collecting
1461 - within a CFunction
1462 If it is, return a descriptive string
1463 For other frames, return False
1464 '''
1465 if self.is_waiting_for_gil():
1466 return 'Waiting for the GIL'
1467 elif self.is_gc_collect():
1468 return 'Garbage-collecting'
1469 else:
1470 # Detect invocations of PyCFunction instances:
1471 older = self.older()
1472 if older and older._gdbframe.name() == 'PyCFunction_Call':
1473 # Within that frame:
1474 # "func" is the local containing the PyObject* of the
1475 # PyCFunctionObject instance
1476 # "f" is the same value, but cast to (PyCFunctionObject*)
1477 # "self" is the (PyObject*) of the 'self'
1478 try:
1479 # Use the prettyprinter for the func:
1480 func = older._gdbframe.read_var('func')
1481 return str(func)
1482 except RuntimeError:
1483 return 'PyCFunction invocation (unable to read "func")'
1484
1485 # This frame isn't worth reporting:
1486 return False
1487
1488 def is_waiting_for_gil(self):
1489 '''Is this frame waiting on the GIL?'''
1490 # This assumes the _POSIX_THREADS version of Python/ceval_gil.h:
1491 name = self._gdbframe.name()
1492 if name:
David Malcolmd08b2102013-05-06 14:47:15 -04001493 return 'pthread_cond_timedwait' in name
David Malcolm8d37ffa2012-06-27 14:15:34 -04001494
1495 def is_gc_collect(self):
Ezio Melotti3f5db392013-01-27 06:20:14 +02001496 '''Is this frame "collect" within the garbage-collector?'''
David Malcolm8d37ffa2012-06-27 14:15:34 -04001497 return self._gdbframe.name() == 'collect'
1498
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001499 def get_pyop(self):
1500 try:
1501 f = self._gdbframe.read_var('f')
Victor Stinnerd2084162011-12-19 13:42:24 +01001502 frame = PyFrameObjectPtr.from_pyobject_ptr(f)
1503 if not frame.is_optimized_out():
1504 return frame
1505 # gdb is unable to get the "f" argument of PyEval_EvalFrameEx()
1506 # because it was "optimized out". Try to get "f" from the frame
1507 # of the caller, PyEval_EvalCodeEx().
1508 orig_frame = frame
1509 caller = self._gdbframe.older()
1510 if caller:
1511 f = caller.read_var('f')
1512 frame = PyFrameObjectPtr.from_pyobject_ptr(f)
1513 if not frame.is_optimized_out():
1514 return frame
1515 return orig_frame
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001516 except ValueError:
1517 return None
1518
1519 @classmethod
1520 def get_selected_frame(cls):
1521 _gdbframe = gdb.selected_frame()
1522 if _gdbframe:
1523 return Frame(_gdbframe)
1524 return None
1525
1526 @classmethod
1527 def get_selected_python_frame(cls):
David Malcolm8d37ffa2012-06-27 14:15:34 -04001528 '''Try to obtain the Frame for the python-related code in the selected
1529 frame, or None'''
1530 frame = cls.get_selected_frame()
1531
1532 while frame:
1533 if frame.is_python_frame():
1534 return frame
1535 frame = frame.older()
1536
1537 # Not found:
1538 return None
1539
1540 @classmethod
1541 def get_selected_bytecode_frame(cls):
1542 '''Try to obtain the Frame for the python bytecode interpreter in the
1543 selected GDB frame, or None'''
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001544 frame = cls.get_selected_frame()
1545
1546 while frame:
1547 if frame.is_evalframeex():
1548 return frame
1549 frame = frame.older()
1550
1551 # Not found:
1552 return None
1553
1554 def print_summary(self):
1555 if self.is_evalframeex():
1556 pyop = self.get_pyop()
1557 if pyop:
Victor Stinner0e5a41b2010-08-17 22:49:25 +00001558 line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1559 write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line))
Victor Stinnerd2084162011-12-19 13:42:24 +01001560 if not pyop.is_optimized_out():
1561 line = pyop.current_line()
1562 if line is not None:
1563 sys.stdout.write(' %s\n' % line.strip())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001564 else:
1565 sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index())
1566 else:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001567 info = self.is_other_python_frame()
1568 if info:
1569 sys.stdout.write('#%i %s\n' % (self.get_index(), info))
1570 else:
1571 sys.stdout.write('#%i\n' % self.get_index())
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001572
Victor Stinnere670c882011-05-13 17:40:15 +02001573 def print_traceback(self):
1574 if self.is_evalframeex():
1575 pyop = self.get_pyop()
1576 if pyop:
1577 pyop.print_traceback()
Victor Stinnerd2084162011-12-19 13:42:24 +01001578 if not pyop.is_optimized_out():
1579 line = pyop.current_line()
1580 if line is not None:
1581 sys.stdout.write(' %s\n' % line.strip())
Victor Stinnere670c882011-05-13 17:40:15 +02001582 else:
1583 sys.stdout.write(' (unable to read python frame information)\n')
1584 else:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001585 info = self.is_other_python_frame()
1586 if info:
1587 sys.stdout.write(' %s\n' % info)
1588 else:
1589 sys.stdout.write(' (not a python frame)\n')
Victor Stinnere670c882011-05-13 17:40:15 +02001590
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001591class PyList(gdb.Command):
1592 '''List the current Python source code, if any
1593
1594 Use
1595 py-list START
1596 to list at a different line number within the python source.
1597
1598 Use
1599 py-list START, END
1600 to list a specific range of lines within the python source.
1601 '''
1602
1603 def __init__(self):
1604 gdb.Command.__init__ (self,
1605 "py-list",
1606 gdb.COMMAND_FILES,
1607 gdb.COMPLETE_NONE)
1608
1609
1610 def invoke(self, args, from_tty):
1611 import re
1612
1613 start = None
1614 end = None
1615
1616 m = re.match(r'\s*(\d+)\s*', args)
1617 if m:
1618 start = int(m.group(0))
1619 end = start + 10
1620
1621 m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args)
1622 if m:
1623 start, end = map(int, m.groups())
1624
David Malcolm8d37ffa2012-06-27 14:15:34 -04001625 # py-list requires an actual PyEval_EvalFrameEx frame:
1626 frame = Frame.get_selected_bytecode_frame()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001627 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001628 print('Unable to locate gdb frame for python bytecode interpreter')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001629 return
1630
1631 pyop = frame.get_pyop()
Victor Stinnerd2084162011-12-19 13:42:24 +01001632 if not pyop or pyop.is_optimized_out():
Antoine Pitroue50240c2013-11-23 17:40:36 +01001633 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001634 return
1635
1636 filename = pyop.filename()
1637 lineno = pyop.current_line_num()
1638
1639 if start is None:
1640 start = lineno - 5
1641 end = lineno + 5
1642
1643 if start<1:
1644 start = 1
1645
Victor Stinnerd57c5c82011-07-01 12:57:44 +02001646 try:
1647 f = open(os_fsencode(filename), 'r')
1648 except IOError as err:
1649 sys.stdout.write('Unable to open %s: %s\n'
1650 % (filename, err))
1651 return
1652 with f:
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001653 all_lines = f.readlines()
1654 # start and end are 1-based, all_lines is 0-based;
1655 # so [start-1:end] as a python slice gives us [start, end] as a
1656 # closed interval
1657 for i, line in enumerate(all_lines[start-1:end]):
1658 linestr = str(i+start)
1659 # Highlight current line:
1660 if i + start == lineno:
1661 linestr = '>' + linestr
1662 sys.stdout.write('%4s %s' % (linestr, line))
1663
1664
1665# ...and register the command:
1666PyList()
1667
1668def move_in_stack(move_up):
1669 '''Move up or down the stack (for the py-up/py-down command)'''
1670 frame = Frame.get_selected_python_frame()
1671 while frame:
1672 if move_up:
1673 iter_frame = frame.older()
1674 else:
1675 iter_frame = frame.newer()
1676
1677 if not iter_frame:
1678 break
1679
David Malcolm8d37ffa2012-06-27 14:15:34 -04001680 if iter_frame.is_python_frame():
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001681 # Result:
Martin v. Löwis5226fd62010-04-21 06:05:58 +00001682 if iter_frame.select():
1683 iter_frame.print_summary()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001684 return
1685
1686 frame = iter_frame
1687
1688 if move_up:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001689 print('Unable to find an older python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001690 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001691 print('Unable to find a newer python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001692
1693class PyUp(gdb.Command):
1694 'Select and print the python stack frame that called this one (if any)'
1695 def __init__(self):
1696 gdb.Command.__init__ (self,
1697 "py-up",
1698 gdb.COMMAND_STACK,
1699 gdb.COMPLETE_NONE)
1700
1701
1702 def invoke(self, args, from_tty):
1703 move_in_stack(move_up=True)
1704
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001705class PyDown(gdb.Command):
1706 'Select and print the python stack frame called by this one (if any)'
1707 def __init__(self):
1708 gdb.Command.__init__ (self,
1709 "py-down",
1710 gdb.COMMAND_STACK,
1711 gdb.COMPLETE_NONE)
1712
1713
1714 def invoke(self, args, from_tty):
1715 move_in_stack(move_up=False)
1716
Victor Stinner50eb60e2010-04-20 22:32:07 +00001717# Not all builds of gdb have gdb.Frame.select
1718if hasattr(gdb.Frame, 'select'):
1719 PyUp()
1720 PyDown()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001721
Victor Stinnere670c882011-05-13 17:40:15 +02001722class PyBacktraceFull(gdb.Command):
1723 'Display the current python frame and all the frames within its call stack (if any)'
1724 def __init__(self):
1725 gdb.Command.__init__ (self,
1726 "py-bt-full",
1727 gdb.COMMAND_STACK,
1728 gdb.COMPLETE_NONE)
1729
1730
1731 def invoke(self, args, from_tty):
1732 frame = Frame.get_selected_python_frame()
1733 while frame:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001734 if frame.is_python_frame():
Victor Stinnere670c882011-05-13 17:40:15 +02001735 frame.print_summary()
1736 frame = frame.older()
1737
1738PyBacktraceFull()
1739
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001740class PyBacktrace(gdb.Command):
1741 'Display the current python frame and all the frames within its call stack (if any)'
1742 def __init__(self):
1743 gdb.Command.__init__ (self,
1744 "py-bt",
1745 gdb.COMMAND_STACK,
1746 gdb.COMPLETE_NONE)
1747
1748
1749 def invoke(self, args, from_tty):
Victor Stinnere670c882011-05-13 17:40:15 +02001750 sys.stdout.write('Traceback (most recent call first):\n')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001751 frame = Frame.get_selected_python_frame()
1752 while frame:
David Malcolm8d37ffa2012-06-27 14:15:34 -04001753 if frame.is_python_frame():
Victor Stinnere670c882011-05-13 17:40:15 +02001754 frame.print_traceback()
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001755 frame = frame.older()
1756
1757PyBacktrace()
1758
1759class PyPrint(gdb.Command):
1760 'Look up the given python variable name, and print it'
1761 def __init__(self):
1762 gdb.Command.__init__ (self,
1763 "py-print",
1764 gdb.COMMAND_DATA,
1765 gdb.COMPLETE_NONE)
1766
1767
1768 def invoke(self, args, from_tty):
1769 name = str(args)
1770
1771 frame = Frame.get_selected_python_frame()
1772 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001773 print('Unable to locate python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001774 return
1775
1776 pyop_frame = frame.get_pyop()
1777 if not pyop_frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001778 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001779 return
1780
1781 pyop_var, scope = pyop_frame.get_var_by_name(name)
1782
1783 if pyop_var:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001784 print('%s %r = %s'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001785 % (scope,
1786 name,
1787 pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
1788 else:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001789 print('%r not found' % name)
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001790
1791PyPrint()
1792
1793class PyLocals(gdb.Command):
1794 'Look up the given python variable name, and print it'
1795 def __init__(self):
1796 gdb.Command.__init__ (self,
1797 "py-locals",
1798 gdb.COMMAND_DATA,
1799 gdb.COMPLETE_NONE)
1800
1801
1802 def invoke(self, args, from_tty):
1803 name = str(args)
1804
1805 frame = Frame.get_selected_python_frame()
1806 if not frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001807 print('Unable to locate python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001808 return
1809
1810 pyop_frame = frame.get_pyop()
1811 if not pyop_frame:
Antoine Pitroue50240c2013-11-23 17:40:36 +01001812 print('Unable to read information on python frame')
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001813 return
1814
1815 for pyop_name, pyop_value in pyop_frame.iter_locals():
Antoine Pitroue50240c2013-11-23 17:40:36 +01001816 print('%s = %s'
Benjamin Peterson6a6666a2010-04-11 21:49:28 +00001817 % (pyop_name.proxyval(set()),
1818 pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)))
1819
1820PyLocals()