Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / cython / src / Cython / Debugger / libpython.py
blobe89bdeeafe6f3f70d0ecde049e234b9199dbe860
1 #!/usr/bin/python
3 # NOTE: this file is taken from the Python source distribution
4 # It can be found under Tools/gdb/libpython.py. It is shipped with Cython
5 # because it's not installed as a python module, and because changes are only
6 # merged into new python versions (v3.2+).
8 '''
9 From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb
10 to be extended with Python code e.g. for library-specific data visualizations,
11 such as for the C++ STL types. Documentation on this API can be seen at:
12 http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
15 This python module deals with the case when the process being debugged (the
16 "inferior process" in gdb parlance) is itself python, or more specifically,
17 linked against libpython. In this situation, almost every item of data is a
18 (PyObject*), and having the debugger merely print their addresses is not very
19 enlightening.
21 This module embeds knowledge about the implementation details of libpython so
22 that we can emit useful visualizations e.g. a string, a list, a dict, a frame
23 giving file/line information and the state of local variables
25 In particular, given a gdb.Value corresponding to a PyObject* in the inferior
26 process, we can generate a "proxy value" within the gdb process. For example,
27 given a PyObject* in the inferior process that is in fact a PyListObject*
28 holding three PyObject* that turn out to be PyStringObject* instances, we can
29 generate a proxy value within the gdb process that is a list of strings:
30 ["foo", "bar", "baz"]
32 Doing so can be expensive for complicated graphs of objects, and could take
33 some time, so we also have a "write_repr" method that writes a representation
34 of the data to a file-like object. This allows us to stop the traversal by
35 having the file-like object raise an exception if it gets too much data.
37 With both "proxyval" and "write_repr" we keep track of the set of all addresses
38 visited so far in the traversal, to avoid infinite recursion due to cycles in
39 the graph of object references.
41 We try to defer gdb.lookup_type() invocations for python types until as late as
42 possible: for a dynamically linked python binary, when the process starts in
43 the debugger, the libpython.so hasn't been dynamically loaded yet, so none of
44 the type names are known to the debugger
46 The module also extends gdb with some python-specific commands.
47 '''
48 from __future__ import with_statement
50 import os
51 import re
52 import sys
53 import struct
54 import locale
55 import atexit
56 import warnings
57 import tempfile
58 import textwrap
59 import itertools
61 import gdb
63 if sys.version_info[0] < 3:
64 # I think this is the only way to fix this bug :'(
65 # http://sourceware.org/bugzilla/show_bug.cgi?id=12285
66 out, err = sys.stdout, sys.stderr
67 reload(sys).setdefaultencoding('UTF-8')
68 sys.stdout = out
69 sys.stderr = err
71 # Look up the gdb.Type for some standard types:
72 _type_char_ptr = gdb.lookup_type('char').pointer() # char*
73 _type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer()
74 _type_void_ptr = gdb.lookup_type('void').pointer() # void*
76 SIZEOF_VOID_P = _type_void_ptr.sizeof
78 Py_TPFLAGS_HEAPTYPE = (1L << 9)
80 Py_TPFLAGS_INT_SUBCLASS = (1L << 23)
81 Py_TPFLAGS_LONG_SUBCLASS = (1L << 24)
82 Py_TPFLAGS_LIST_SUBCLASS = (1L << 25)
83 Py_TPFLAGS_TUPLE_SUBCLASS = (1L << 26)
84 Py_TPFLAGS_STRING_SUBCLASS = (1L << 27)
85 Py_TPFLAGS_BYTES_SUBCLASS = (1L << 27)
86 Py_TPFLAGS_UNICODE_SUBCLASS = (1L << 28)
87 Py_TPFLAGS_DICT_SUBCLASS = (1L << 29)
88 Py_TPFLAGS_BASE_EXC_SUBCLASS = (1L << 30)
89 Py_TPFLAGS_TYPE_SUBCLASS = (1L << 31)
91 MAX_OUTPUT_LEN = 1024
93 hexdigits = "0123456789abcdef"
95 ENCODING = locale.getpreferredencoding()
97 class NullPyObjectPtr(RuntimeError):
98 pass
101 def safety_limit(val):
102 # Given a integer value from the process being debugged, limit it to some
103 # safety threshold so that arbitrary breakage within said process doesn't
104 # break the gdb process too much (e.g. sizes of iterations, sizes of lists)
105 return min(val, 1000)
108 def safe_range(val):
109 # As per range, but don't trust the value too much: cap it to a safety
110 # threshold in case the data was corrupted
111 return xrange(safety_limit(val))
113 def write_unicode(file, text):
114 # Write a byte or unicode string to file. Unicode strings are encoded to
115 # ENCODING encoding with 'backslashreplace' error handler to avoid
116 # UnicodeEncodeError.
117 if isinstance(text, unicode):
118 text = text.encode(ENCODING, 'backslashreplace')
119 file.write(text)
121 def os_fsencode(filename):
122 if not isinstance(filename, unicode):
123 return filename
124 encoding = sys.getfilesystemencoding()
125 if encoding == 'mbcs':
126 # mbcs doesn't support surrogateescape
127 return filename.encode(encoding)
128 encoded = []
129 for char in filename:
130 # surrogateescape error handler
131 if 0xDC80 <= ord(char) <= 0xDCFF:
132 byte = chr(ord(char) - 0xDC00)
133 else:
134 byte = char.encode(encoding)
135 encoded.append(byte)
136 return ''.join(encoded)
138 class StringTruncated(RuntimeError):
139 pass
141 class TruncatedStringIO(object):
142 '''Similar to cStringIO, but can truncate the output by raising a
143 StringTruncated exception'''
144 def __init__(self, maxlen=None):
145 self._val = ''
146 self.maxlen = maxlen
148 def write(self, data):
149 if self.maxlen:
150 if len(data) + len(self._val) > self.maxlen:
151 # Truncation:
152 self._val += data[0:self.maxlen - len(self._val)]
153 raise StringTruncated()
155 self._val += data
157 def getvalue(self):
158 return self._val
161 # pretty printer lookup
162 all_pretty_typenames = set()
164 class PrettyPrinterTrackerMeta(type):
166 def __init__(self, name, bases, dict):
167 super(PrettyPrinterTrackerMeta, self).__init__(name, bases, dict)
168 all_pretty_typenames.add(self._typename)
171 class PyObjectPtr(object):
173 Class wrapping a gdb.Value that's a either a (PyObject*) within the
174 inferior process, or some subclass pointer e.g. (PyStringObject*)
176 There will be a subclass for every refined PyObject type that we care
177 about.
179 Note that at every stage the underlying pointer could be NULL, point
180 to corrupt data, etc; this is the debugger, after all.
183 __metaclass__ = PrettyPrinterTrackerMeta
185 _typename = 'PyObject'
187 def __init__(self, gdbval, cast_to=None):
188 if cast_to:
189 self._gdbval = gdbval.cast(cast_to)
190 else:
191 self._gdbval = gdbval
193 def field(self, name):
195 Get the gdb.Value for the given field within the PyObject, coping with
196 some python 2 versus python 3 differences.
198 Various libpython types are defined using the "PyObject_HEAD" and
199 "PyObject_VAR_HEAD" macros.
201 In Python 2, this these are defined so that "ob_type" and (for a var
202 object) "ob_size" are fields of the type in question.
204 In Python 3, this is defined as an embedded PyVarObject type thus:
205 PyVarObject ob_base;
206 so that the "ob_size" field is located insize the "ob_base" field, and
207 the "ob_type" is most easily accessed by casting back to a (PyObject*).
209 if self.is_null():
210 raise NullPyObjectPtr(self)
212 if name == 'ob_type':
213 pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type())
214 return pyo_ptr.dereference()[name]
216 if name == 'ob_size':
217 pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type())
218 return pyo_ptr.dereference()[name]
220 # General case: look it up inside the object:
221 return self._gdbval.dereference()[name]
223 def pyop_field(self, name):
225 Get a PyObjectPtr for the given PyObject* field within this PyObject,
226 coping with some python 2 versus python 3 differences.
228 return PyObjectPtr.from_pyobject_ptr(self.field(name))
230 def write_field_repr(self, name, out, visited):
232 Extract the PyObject* field named "name", and write its representation
233 to file-like object "out"
235 field_obj = self.pyop_field(name)
236 field_obj.write_repr(out, visited)
238 def get_truncated_repr(self, maxlen):
240 Get a repr-like string for the data, but truncate it at "maxlen" bytes
241 (ending the object graph traversal as soon as you do)
243 out = TruncatedStringIO(maxlen)
244 try:
245 self.write_repr(out, set())
246 except StringTruncated:
247 # Truncation occurred:
248 return out.getvalue() + '...(truncated)'
250 # No truncation occurred:
251 return out.getvalue()
253 def type(self):
254 return PyTypeObjectPtr(self.field('ob_type'))
256 def is_null(self):
257 return 0 == long(self._gdbval)
259 def is_optimized_out(self):
261 Is the value of the underlying PyObject* visible to the debugger?
263 This can vary with the precise version of the compiler used to build
264 Python, and the precise version of gdb.
266 See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
267 PyEval_EvalFrameEx's "f"
269 return self._gdbval.is_optimized_out
271 def safe_tp_name(self):
272 try:
273 return self.type().field('tp_name').string()
274 except NullPyObjectPtr:
275 # NULL tp_name?
276 return 'unknown'
277 except RuntimeError:
278 # Can't even read the object at all?
279 return 'unknown'
281 def proxyval(self, visited):
283 Scrape a value from the inferior process, and try to represent it
284 within the gdb process, whilst (hopefully) avoiding crashes when
285 the remote data is corrupt.
287 Derived classes will override this.
289 For example, a PyIntObject* with ob_ival 42 in the inferior process
290 should result in an int(42) in this process.
292 visited: a set of all gdb.Value pyobject pointers already visited
293 whilst generating this value (to guard against infinite recursion when
294 visiting object graphs with loops). Analogous to Py_ReprEnter and
295 Py_ReprLeave
298 class FakeRepr(object):
300 Class representing a non-descript PyObject* value in the inferior
301 process for when we don't have a custom scraper, intended to have
302 a sane repr().
305 def __init__(self, tp_name, address):
306 self.tp_name = tp_name
307 self.address = address
309 def __repr__(self):
310 # For the NULL pointer, we have no way of knowing a type, so
311 # special-case it as per
312 # http://bugs.python.org/issue8032#msg100882
313 if self.address == 0:
314 return '0x0'
315 return '<%s at remote 0x%x>' % (self.tp_name, self.address)
317 return FakeRepr(self.safe_tp_name(),
318 long(self._gdbval))
320 def write_repr(self, out, visited):
322 Write a string representation of the value scraped from the inferior
323 process to "out", a file-like object.
325 # Default implementation: generate a proxy value and write its repr
326 # However, this could involve a lot of work for complicated objects,
327 # so for derived classes we specialize this
328 return out.write(repr(self.proxyval(visited)))
330 @classmethod
331 def subclass_from_type(cls, t):
333 Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
334 (PyTypeObject*), determine the corresponding subclass of PyObjectPtr
335 to use
337 Ideally, we would look up the symbols for the global types, but that
338 isn't working yet:
339 (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
340 Traceback (most recent call last):
341 File "<string>", line 1, in <module>
342 NotImplementedError: Symbol type not yet supported in Python scripts.
343 Error while executing Python code.
345 For now, we use tp_flags, after doing some string comparisons on the
346 tp_name for some special-cases that don't seem to be visible through
347 flags
349 try:
350 tp_name = t.field('tp_name').string()
351 tp_flags = int(t.field('tp_flags'))
352 except RuntimeError:
353 # Handle any kind of error e.g. NULL ptrs by simply using the base
354 # class
355 return cls
357 #print 'tp_flags = 0x%08x' % tp_flags
358 #print 'tp_name = %r' % tp_name
360 name_map = {'bool': PyBoolObjectPtr,
361 'classobj': PyClassObjectPtr,
362 'instance': PyInstanceObjectPtr,
363 'NoneType': PyNoneStructPtr,
364 'frame': PyFrameObjectPtr,
365 'set' : PySetObjectPtr,
366 'frozenset' : PySetObjectPtr,
367 'builtin_function_or_method' : PyCFunctionObjectPtr,
369 if tp_name in name_map:
370 return name_map[tp_name]
372 if tp_flags & (Py_TPFLAGS_HEAPTYPE|Py_TPFLAGS_TYPE_SUBCLASS):
373 return PyTypeObjectPtr
375 if tp_flags & Py_TPFLAGS_INT_SUBCLASS:
376 return PyIntObjectPtr
377 if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
378 return PyLongObjectPtr
379 if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
380 return PyListObjectPtr
381 if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
382 return PyTupleObjectPtr
383 if tp_flags & Py_TPFLAGS_STRING_SUBCLASS:
384 try:
385 gdb.lookup_type('PyBytesObject')
386 return PyBytesObjectPtr
387 except RuntimeError:
388 return PyStringObjectPtr
389 if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
390 return PyUnicodeObjectPtr
391 if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
392 return PyDictObjectPtr
393 if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
394 return PyBaseExceptionObjectPtr
396 # Use the base class:
397 return cls
399 @classmethod
400 def from_pyobject_ptr(cls, gdbval):
402 Try to locate the appropriate derived class dynamically, and cast
403 the pointer accordingly.
405 try:
406 p = PyObjectPtr(gdbval)
407 cls = cls.subclass_from_type(p.type())
408 return cls(gdbval, cast_to=cls.get_gdb_type())
409 except RuntimeError, exc:
410 # Handle any kind of error e.g. NULL ptrs by simply using the base
411 # class
412 pass
413 return cls(gdbval)
415 @classmethod
416 def get_gdb_type(cls):
417 return gdb.lookup_type(cls._typename).pointer()
419 def as_address(self):
420 return long(self._gdbval)
423 class PyVarObjectPtr(PyObjectPtr):
424 _typename = 'PyVarObject'
426 class ProxyAlreadyVisited(object):
428 Placeholder proxy to use when protecting against infinite recursion due to
429 loops in the object graph.
431 Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave
433 def __init__(self, rep):
434 self._rep = rep
436 def __repr__(self):
437 return self._rep
440 def _write_instance_repr(out, visited, name, pyop_attrdict, address):
441 '''Shared code for use by old-style and new-style classes:
442 write a representation to file-like object "out"'''
443 out.write('<')
444 out.write(name)
446 # Write dictionary of instance attributes:
447 if isinstance(pyop_attrdict, PyDictObjectPtr):
448 out.write('(')
449 first = True
450 for pyop_arg, pyop_val in pyop_attrdict.iteritems():
451 if not first:
452 out.write(', ')
453 first = False
454 out.write(pyop_arg.proxyval(visited))
455 out.write('=')
456 pyop_val.write_repr(out, visited)
457 out.write(')')
458 out.write(' at remote 0x%x>' % address)
461 class InstanceProxy(object):
463 def __init__(self, cl_name, attrdict, address):
464 self.cl_name = cl_name
465 self.attrdict = attrdict
466 self.address = address
468 def __repr__(self):
469 if isinstance(self.attrdict, dict):
470 kwargs = ', '.join(["%s=%r" % (arg, val)
471 for arg, val in self.attrdict.iteritems()])
472 return '<%s(%s) at remote 0x%x>' % (self.cl_name,
473 kwargs, self.address)
474 else:
475 return '<%s at remote 0x%x>' % (self.cl_name,
476 self.address)
478 def _PyObject_VAR_SIZE(typeobj, nitems):
479 return ( ( typeobj.field('tp_basicsize') +
480 nitems * typeobj.field('tp_itemsize') +
481 (SIZEOF_VOID_P - 1)
482 ) & ~(SIZEOF_VOID_P - 1)
483 ).cast(gdb.lookup_type('size_t'))
485 class PyTypeObjectPtr(PyObjectPtr):
486 _typename = 'PyTypeObject'
488 def get_attr_dict(self):
490 Get the PyDictObject ptr representing the attribute dictionary
491 (or None if there's a problem)
493 try:
494 typeobj = self.type()
495 dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
496 if dictoffset != 0:
497 if dictoffset < 0:
498 type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
499 tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
500 if tsize < 0:
501 tsize = -tsize
502 size = _PyObject_VAR_SIZE(typeobj, tsize)
503 dictoffset += size
504 assert dictoffset > 0
505 assert dictoffset % SIZEOF_VOID_P == 0
507 dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset
508 PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
509 dictptr = dictptr.cast(PyObjectPtrPtr)
510 return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
511 except RuntimeError:
512 # Corrupt data somewhere; fail safe
513 pass
515 # Not found, or some kind of error:
516 return None
518 def proxyval(self, visited):
520 Support for new-style classes.
522 Currently we just locate the dictionary using a transliteration to
523 python of _PyObject_GetDictPtr, ignoring descriptors
525 # Guard against infinite loops:
526 if self.as_address() in visited:
527 return ProxyAlreadyVisited('<...>')
528 visited.add(self.as_address())
530 pyop_attr_dict = self.get_attr_dict()
531 if pyop_attr_dict:
532 attr_dict = pyop_attr_dict.proxyval(visited)
533 else:
534 attr_dict = {}
535 tp_name = self.safe_tp_name()
537 # New-style class:
538 return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
540 def write_repr(self, out, visited):
541 # Guard against infinite loops:
542 if self.as_address() in visited:
543 out.write('<...>')
544 return
545 visited.add(self.as_address())
547 try:
548 tp_name = self.field('tp_name').string()
549 except RuntimeError:
550 tp_name = 'unknown'
552 out.write('<type %s at remote 0x%x>' % (tp_name,
553 self.as_address()))
554 # pyop_attrdict = self.get_attr_dict()
555 # _write_instance_repr(out, visited,
556 # self.safe_tp_name(), pyop_attrdict, self.as_address())
558 class ProxyException(Exception):
559 def __init__(self, tp_name, args):
560 self.tp_name = tp_name
561 self.args = args
563 def __repr__(self):
564 return '%s%r' % (self.tp_name, self.args)
566 class PyBaseExceptionObjectPtr(PyObjectPtr):
568 Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception
569 within the process being debugged.
571 _typename = 'PyBaseExceptionObject'
573 def proxyval(self, visited):
574 # Guard against infinite loops:
575 if self.as_address() in visited:
576 return ProxyAlreadyVisited('(...)')
577 visited.add(self.as_address())
578 arg_proxy = self.pyop_field('args').proxyval(visited)
579 return ProxyException(self.safe_tp_name(),
580 arg_proxy)
582 def write_repr(self, out, visited):
583 # Guard against infinite loops:
584 if self.as_address() in visited:
585 out.write('(...)')
586 return
587 visited.add(self.as_address())
589 out.write(self.safe_tp_name())
590 self.write_field_repr('args', out, visited)
593 class PyClassObjectPtr(PyObjectPtr):
595 Class wrapping a gdb.Value that's a PyClassObject* i.e. a <classobj>
596 instance within the process being debugged.
598 _typename = 'PyClassObject'
601 class BuiltInFunctionProxy(object):
602 def __init__(self, ml_name):
603 self.ml_name = ml_name
605 def __repr__(self):
606 return "<built-in function %s>" % self.ml_name
608 class BuiltInMethodProxy(object):
609 def __init__(self, ml_name, pyop_m_self):
610 self.ml_name = ml_name
611 self.pyop_m_self = pyop_m_self
613 def __repr__(self):
614 return ('<built-in method %s of %s object at remote 0x%x>'
615 % (self.ml_name,
616 self.pyop_m_self.safe_tp_name(),
617 self.pyop_m_self.as_address())
620 class PyCFunctionObjectPtr(PyObjectPtr):
622 Class wrapping a gdb.Value that's a PyCFunctionObject*
623 (see Include/methodobject.h and Objects/methodobject.c)
625 _typename = 'PyCFunctionObject'
627 def proxyval(self, visited):
628 m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
629 ml_name = m_ml['ml_name'].string()
631 pyop_m_self = self.pyop_field('m_self')
632 if pyop_m_self.is_null():
633 return BuiltInFunctionProxy(ml_name)
634 else:
635 return BuiltInMethodProxy(ml_name, pyop_m_self)
638 class PyCodeObjectPtr(PyObjectPtr):
640 Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
641 within the process being debugged.
643 _typename = 'PyCodeObject'
645 def addr2line(self, addrq):
647 Get the line number for a given bytecode offset
649 Analogous to PyCode_Addr2Line; translated from pseudocode in
650 Objects/lnotab_notes.txt
652 co_lnotab = self.pyop_field('co_lnotab').proxyval(set())
654 # Initialize lineno to co_firstlineno as per PyCode_Addr2Line
655 # not 0, as lnotab_notes.txt has it:
656 lineno = int_from_int(self.field('co_firstlineno'))
658 addr = 0
659 for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
660 addr += ord(addr_incr)
661 if addr > addrq:
662 return lineno
663 lineno += ord(line_incr)
664 return lineno
667 class PyDictObjectPtr(PyObjectPtr):
669 Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
670 within the process being debugged.
672 _typename = 'PyDictObject'
674 def iteritems(self):
676 Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
677 analagous to dict.iteritems()
679 for i in safe_range(self.field('ma_mask') + 1):
680 ep = self.field('ma_table') + i
681 pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
682 if not pyop_value.is_null():
683 pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
684 yield (pyop_key, pyop_value)
686 def proxyval(self, visited):
687 # Guard against infinite loops:
688 if self.as_address() in visited:
689 return ProxyAlreadyVisited('{...}')
690 visited.add(self.as_address())
692 result = {}
693 for pyop_key, pyop_value in self.iteritems():
694 proxy_key = pyop_key.proxyval(visited)
695 proxy_value = pyop_value.proxyval(visited)
696 result[proxy_key] = proxy_value
697 return result
699 def write_repr(self, out, visited):
700 # Guard against infinite loops:
701 if self.as_address() in visited:
702 out.write('{...}')
703 return
704 visited.add(self.as_address())
706 out.write('{')
707 first = True
708 for pyop_key, pyop_value in self.iteritems():
709 if not first:
710 out.write(', ')
711 first = False
712 pyop_key.write_repr(out, visited)
713 out.write(': ')
714 pyop_value.write_repr(out, visited)
715 out.write('}')
717 class PyInstanceObjectPtr(PyObjectPtr):
718 _typename = 'PyInstanceObject'
720 def proxyval(self, visited):
721 # Guard against infinite loops:
722 if self.as_address() in visited:
723 return ProxyAlreadyVisited('<...>')
724 visited.add(self.as_address())
726 # Get name of class:
727 in_class = self.pyop_field('in_class')
728 cl_name = in_class.pyop_field('cl_name').proxyval(visited)
730 # Get dictionary of instance attributes:
731 in_dict = self.pyop_field('in_dict').proxyval(visited)
733 # Old-style class:
734 return InstanceProxy(cl_name, in_dict, long(self._gdbval))
736 def write_repr(self, out, visited):
737 # Guard against infinite loops:
738 if self.as_address() in visited:
739 out.write('<...>')
740 return
741 visited.add(self.as_address())
743 # Old-style class:
745 # Get name of class:
746 in_class = self.pyop_field('in_class')
747 cl_name = in_class.pyop_field('cl_name').proxyval(visited)
749 # Get dictionary of instance attributes:
750 pyop_in_dict = self.pyop_field('in_dict')
752 _write_instance_repr(out, visited,
753 cl_name, pyop_in_dict, self.as_address())
755 class PyIntObjectPtr(PyObjectPtr):
756 _typename = 'PyIntObject'
758 def proxyval(self, visited):
759 result = int_from_int(self.field('ob_ival'))
760 return result
762 class PyListObjectPtr(PyObjectPtr):
763 _typename = 'PyListObject'
765 def __getitem__(self, i):
766 # Get the gdb.Value for the (PyObject*) with the given index:
767 field_ob_item = self.field('ob_item')
768 return field_ob_item[i]
770 def proxyval(self, visited):
771 # Guard against infinite loops:
772 if self.as_address() in visited:
773 return ProxyAlreadyVisited('[...]')
774 visited.add(self.as_address())
776 result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
777 for i in safe_range(int_from_int(self.field('ob_size')))]
778 return result
780 def write_repr(self, out, visited):
781 # Guard against infinite loops:
782 if self.as_address() in visited:
783 out.write('[...]')
784 return
785 visited.add(self.as_address())
787 out.write('[')
788 for i in safe_range(int_from_int(self.field('ob_size'))):
789 if i > 0:
790 out.write(', ')
791 element = PyObjectPtr.from_pyobject_ptr(self[i])
792 element.write_repr(out, visited)
793 out.write(']')
795 class PyLongObjectPtr(PyObjectPtr):
796 _typename = 'PyLongObject'
798 def proxyval(self, visited):
800 Python's Include/longobjrep.h has this declaration:
801 struct _longobject {
802 PyObject_VAR_HEAD
803 digit ob_digit[1];
806 with this description:
807 The absolute value of a number is equal to
808 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
809 Negative numbers are represented with ob_size < 0;
810 zero is represented by ob_size == 0.
812 where SHIFT can be either:
813 #define PyLong_SHIFT 30
814 #define PyLong_SHIFT 15
816 ob_size = long(self.field('ob_size'))
817 if ob_size == 0:
818 return 0L
820 ob_digit = self.field('ob_digit')
822 if gdb.lookup_type('digit').sizeof == 2:
823 SHIFT = 15L
824 else:
825 SHIFT = 30L
827 digits = [long(ob_digit[i]) * 2**(SHIFT*i)
828 for i in safe_range(abs(ob_size))]
829 result = sum(digits)
830 if ob_size < 0:
831 result = -result
832 return result
834 def write_repr(self, out, visited):
835 # Write this out as a Python 3 int literal, i.e. without the "L" suffix
836 proxy = self.proxyval(visited)
837 out.write("%s" % proxy)
840 class PyBoolObjectPtr(PyLongObjectPtr):
842 Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
843 <bool> instances (Py_True/Py_False) within the process being debugged.
845 _typename = 'PyBoolObject'
847 def proxyval(self, visited):
848 castto = gdb.lookup_type('PyLongObject').pointer()
849 self._gdbval = self._gdbval.cast(castto)
850 return bool(PyLongObjectPtr(self._gdbval).proxyval(visited))
853 class PyNoneStructPtr(PyObjectPtr):
855 Class wrapping a gdb.Value that's a PyObject* pointing to the
856 singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type
858 _typename = 'PyObject'
860 def proxyval(self, visited):
861 return None
864 class PyFrameObjectPtr(PyObjectPtr):
865 _typename = 'PyFrameObject'
867 def __init__(self, gdbval, cast_to=None):
868 PyObjectPtr.__init__(self, gdbval, cast_to)
870 if not self.is_optimized_out():
871 self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
872 self.co_name = self.co.pyop_field('co_name')
873 self.co_filename = self.co.pyop_field('co_filename')
875 self.f_lineno = int_from_int(self.field('f_lineno'))
876 self.f_lasti = int_from_int(self.field('f_lasti'))
877 self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
878 self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))
880 def iter_locals(self):
882 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
883 the local variables of this frame
885 if self.is_optimized_out():
886 return
888 f_localsplus = self.field('f_localsplus')
889 for i in safe_range(self.co_nlocals):
890 pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
891 if not pyop_value.is_null():
892 pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
893 yield (pyop_name, pyop_value)
895 def iter_globals(self):
897 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
898 the global variables of this frame
900 if self.is_optimized_out():
901 return
903 pyop_globals = self.pyop_field('f_globals')
904 return pyop_globals.iteritems()
906 def iter_builtins(self):
908 Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
909 the builtin variables
911 if self.is_optimized_out():
912 return
914 pyop_builtins = self.pyop_field('f_builtins')
915 return pyop_builtins.iteritems()
917 def get_var_by_name(self, name):
919 Look for the named local variable, returning a (PyObjectPtr, scope) pair
920 where scope is a string 'local', 'global', 'builtin'
922 If not found, return (None, None)
924 for pyop_name, pyop_value in self.iter_locals():
925 if name == pyop_name.proxyval(set()):
926 return pyop_value, 'local'
927 for pyop_name, pyop_value in self.iter_globals():
928 if name == pyop_name.proxyval(set()):
929 return pyop_value, 'global'
930 for pyop_name, pyop_value in self.iter_builtins():
931 if name == pyop_name.proxyval(set()):
932 return pyop_value, 'builtin'
933 return None, None
935 def filename(self):
936 '''Get the path of the current Python source file, as a string'''
937 if self.is_optimized_out():
938 return '(frame information optimized out)'
939 return self.co_filename.proxyval(set())
941 def current_line_num(self):
942 '''Get current line number as an integer (1-based)
944 Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
946 See Objects/lnotab_notes.txt
948 if self.is_optimized_out():
949 return None
950 f_trace = self.field('f_trace')
951 if long(f_trace) != 0:
952 # we have a non-NULL f_trace:
953 return self.f_lineno
954 else:
955 #try:
956 return self.co.addr2line(self.f_lasti)
957 #except ValueError:
958 # return self.f_lineno
960 def current_line(self):
961 '''Get the text of the current source line as a string, with a trailing
962 newline character'''
963 if self.is_optimized_out():
964 return '(frame information optimized out)'
965 filename = self.filename()
966 with open(os_fsencode(filename), 'r') as f:
967 all_lines = f.readlines()
968 # Convert from 1-based current_line_num to 0-based list offset:
969 return all_lines[self.current_line_num()-1]
971 def write_repr(self, out, visited):
972 if self.is_optimized_out():
973 out.write('(frame information optimized out)')
974 return
975 out.write('Frame 0x%x, for file %s, line %i, in %s ('
976 % (self.as_address(),
977 self.co_filename.proxyval(visited),
978 self.current_line_num(),
979 self.co_name.proxyval(visited)))
980 first = True
981 for pyop_name, pyop_value in self.iter_locals():
982 if not first:
983 out.write(', ')
984 first = False
986 out.write(pyop_name.proxyval(visited))
987 out.write('=')
988 pyop_value.write_repr(out, visited)
990 out.write(')')
992 class PySetObjectPtr(PyObjectPtr):
993 _typename = 'PySetObject'
995 def proxyval(self, visited):
996 # Guard against infinite loops:
997 if self.as_address() in visited:
998 return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
999 visited.add(self.as_address())
1001 members = []
1002 table = self.field('table')
1003 for i in safe_range(self.field('mask')+1):
1004 setentry = table[i]
1005 key = setentry['key']
1006 if key != 0:
1007 key_proxy = PyObjectPtr.from_pyobject_ptr(key).proxyval(visited)
1008 if key_proxy != '<dummy key>':
1009 members.append(key_proxy)
1010 if self.safe_tp_name() == 'frozenset':
1011 return frozenset(members)
1012 else:
1013 return set(members)
1015 def write_repr(self, out, visited):
1016 # Emulate Python 3's set_repr
1017 tp_name = self.safe_tp_name()
1019 # Guard against infinite loops:
1020 if self.as_address() in visited:
1021 out.write('(...)')
1022 return
1023 visited.add(self.as_address())
1025 # Python 3's set_repr special-cases the empty set:
1026 if not self.field('used'):
1027 out.write(tp_name)
1028 out.write('()')
1029 return
1031 # Python 3 uses {} for set literals:
1032 if tp_name != 'set':
1033 out.write(tp_name)
1034 out.write('(')
1036 out.write('{')
1037 first = True
1038 table = self.field('table')
1039 for i in safe_range(self.field('mask')+1):
1040 setentry = table[i]
1041 key = setentry['key']
1042 if key != 0:
1043 pyop_key = PyObjectPtr.from_pyobject_ptr(key)
1044 key_proxy = pyop_key.proxyval(visited) # FIXME!
1045 if key_proxy != '<dummy key>':
1046 if not first:
1047 out.write(', ')
1048 first = False
1049 pyop_key.write_repr(out, visited)
1050 out.write('}')
1052 if tp_name != 'set':
1053 out.write(')')
1056 class PyBytesObjectPtr(PyObjectPtr):
1057 _typename = 'PyBytesObject'
1059 def __str__(self):
1060 field_ob_size = self.field('ob_size')
1061 field_ob_sval = self.field('ob_sval')
1062 return ''.join(struct.pack('b', field_ob_sval[i])
1063 for i in safe_range(field_ob_size))
1065 def proxyval(self, visited):
1066 return str(self)
1068 def write_repr(self, out, visited, py3=True):
1069 # Write this out as a Python 3 bytes literal, i.e. with a "b" prefix
1071 # Get a PyStringObject* within the Python 2 gdb process:
1072 proxy = self.proxyval(visited)
1074 # Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr
1075 # to Python 2 code:
1076 quote = "'"
1077 if "'" in proxy and not '"' in proxy:
1078 quote = '"'
1080 if py3:
1081 out.write('b')
1083 out.write(quote)
1084 for byte in proxy:
1085 if byte == quote or byte == '\\':
1086 out.write('\\')
1087 out.write(byte)
1088 elif byte == '\t':
1089 out.write('\\t')
1090 elif byte == '\n':
1091 out.write('\\n')
1092 elif byte == '\r':
1093 out.write('\\r')
1094 elif byte < ' ' or ord(byte) >= 0x7f:
1095 out.write('\\x')
1096 out.write(hexdigits[(ord(byte) & 0xf0) >> 4])
1097 out.write(hexdigits[ord(byte) & 0xf])
1098 else:
1099 out.write(byte)
1100 out.write(quote)
1102 class PyStringObjectPtr(PyBytesObjectPtr):
1103 _typename = 'PyStringObject'
1105 def write_repr(self, out, visited):
1106 return super(PyStringObjectPtr, self).write_repr(out, visited, py3=False)
1108 class PyTupleObjectPtr(PyObjectPtr):
1109 _typename = 'PyTupleObject'
1111 def __getitem__(self, i):
1112 # Get the gdb.Value for the (PyObject*) with the given index:
1113 field_ob_item = self.field('ob_item')
1114 return field_ob_item[i]
1116 def proxyval(self, visited):
1117 # Guard against infinite loops:
1118 if self.as_address() in visited:
1119 return ProxyAlreadyVisited('(...)')
1120 visited.add(self.as_address())
1122 result = tuple([PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
1123 for i in safe_range(int_from_int(self.field('ob_size')))])
1124 return result
1126 def write_repr(self, out, visited):
1127 # Guard against infinite loops:
1128 if self.as_address() in visited:
1129 out.write('(...)')
1130 return
1131 visited.add(self.as_address())
1133 out.write('(')
1134 for i in safe_range(int_from_int(self.field('ob_size'))):
1135 if i > 0:
1136 out.write(', ')
1137 element = PyObjectPtr.from_pyobject_ptr(self[i])
1138 element.write_repr(out, visited)
1139 if self.field('ob_size') == 1:
1140 out.write(',)')
1141 else:
1142 out.write(')')
1145 def _unichr_is_printable(char):
1146 # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
1147 if char == u" ":
1148 return True
1149 import unicodedata
1150 return unicodedata.category(char) not in ("C", "Z")
1152 if sys.maxunicode >= 0x10000:
1153 _unichr = unichr
1154 else:
1155 # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
1156 def _unichr(x):
1157 if x < 0x10000:
1158 return unichr(x)
1159 x -= 0x10000
1160 ch1 = 0xD800 | (x >> 10)
1161 ch2 = 0xDC00 | (x & 0x3FF)
1162 return unichr(ch1) + unichr(ch2)
1164 class PyUnicodeObjectPtr(PyObjectPtr):
1165 _typename = 'PyUnicodeObject'
1167 def char_width(self):
1168 _type_Py_UNICODE = gdb.lookup_type('Py_UNICODE')
1169 return _type_Py_UNICODE.sizeof
1171 def proxyval(self, visited):
1172 # From unicodeobject.h:
1173 # Py_ssize_t length; /* Length of raw Unicode data in buffer */
1174 # Py_UNICODE *str; /* Raw Unicode buffer */
1175 field_length = long(self.field('length'))
1176 field_str = self.field('str')
1178 # Gather a list of ints from the Py_UNICODE array; these are either
1179 # UCS-2 or UCS-4 code points:
1180 if self.char_width() > 2:
1181 Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
1182 else:
1183 # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
1184 # inferior process: we must join surrogate pairs.
1185 Py_UNICODEs = []
1186 i = 0
1187 limit = safety_limit(field_length)
1188 while i < limit:
1189 ucs = int(field_str[i])
1190 i += 1
1191 if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
1192 Py_UNICODEs.append(ucs)
1193 continue
1194 # This could be a surrogate pair.
1195 ucs2 = int(field_str[i])
1196 if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
1197 continue
1198 code = (ucs & 0x03FF) << 10
1199 code |= ucs2 & 0x03FF
1200 code += 0x00010000
1201 Py_UNICODEs.append(code)
1202 i += 1
1204 # Convert the int code points to unicode characters, and generate a
1205 # local unicode instance.
1206 # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
1207 result = u''.join([_unichr(ucs) for ucs in Py_UNICODEs])
1208 return result
1210 def write_repr(self, out, visited):
1211 # Get a PyUnicodeObject* within the Python 2 gdb process:
1212 proxy = self.proxyval(visited)
1214 # Transliteration of Python 3's Object/unicodeobject.c:unicode_repr
1215 # to Python 2:
1216 try:
1217 gdb.parse_and_eval('PyString_Type')
1218 except RuntimeError:
1219 # Python 3, don't write 'u' as prefix
1220 pass
1221 else:
1222 # Python 2, write the 'u'
1223 out.write('u')
1225 if "'" in proxy and '"' not in proxy:
1226 quote = '"'
1227 else:
1228 quote = "'"
1229 out.write(quote)
1231 i = 0
1232 while i < len(proxy):
1233 ch = proxy[i]
1234 i += 1
1236 # Escape quotes and backslashes
1237 if ch == quote or ch == '\\':
1238 out.write('\\')
1239 out.write(ch)
1241 # Map special whitespace to '\t', \n', '\r'
1242 elif ch == '\t':
1243 out.write('\\t')
1244 elif ch == '\n':
1245 out.write('\\n')
1246 elif ch == '\r':
1247 out.write('\\r')
1249 # Map non-printable US ASCII to '\xhh' */
1250 elif ch < ' ' or ch == 0x7F:
1251 out.write('\\x')
1252 out.write(hexdigits[(ord(ch) >> 4) & 0x000F])
1253 out.write(hexdigits[ord(ch) & 0x000F])
1255 # Copy ASCII characters as-is
1256 elif ord(ch) < 0x7F:
1257 out.write(ch)
1259 # Non-ASCII characters
1260 else:
1261 ucs = ch
1262 ch2 = None
1263 if sys.maxunicode < 0x10000:
1264 # If sizeof(Py_UNICODE) is 2 here (in gdb), join
1265 # surrogate pairs before calling _unichr_is_printable.
1266 if (i < len(proxy)
1267 and 0xD800 <= ord(ch) < 0xDC00 \
1268 and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
1269 ch2 = proxy[i]
1270 ucs = ch + ch2
1271 i += 1
1273 # Unfortuately, Python 2's unicode type doesn't seem
1274 # to expose the "isprintable" method
1275 printable = _unichr_is_printable(ucs)
1276 if printable:
1277 try:
1278 ucs.encode(ENCODING)
1279 except UnicodeEncodeError:
1280 printable = False
1282 # Map Unicode whitespace and control characters
1283 # (categories Z* and C* except ASCII space)
1284 if not printable:
1285 if ch2 is not None:
1286 # Match Python 3's representation of non-printable
1287 # wide characters.
1288 code = (ord(ch) & 0x03FF) << 10
1289 code |= ord(ch2) & 0x03FF
1290 code += 0x00010000
1291 else:
1292 code = ord(ucs)
1294 # Map 8-bit characters to '\\xhh'
1295 if code <= 0xff:
1296 out.write('\\x')
1297 out.write(hexdigits[(code >> 4) & 0x000F])
1298 out.write(hexdigits[code & 0x000F])
1299 # Map 21-bit characters to '\U00xxxxxx'
1300 elif code >= 0x10000:
1301 out.write('\\U')
1302 out.write(hexdigits[(code >> 28) & 0x0000000F])
1303 out.write(hexdigits[(code >> 24) & 0x0000000F])
1304 out.write(hexdigits[(code >> 20) & 0x0000000F])
1305 out.write(hexdigits[(code >> 16) & 0x0000000F])
1306 out.write(hexdigits[(code >> 12) & 0x0000000F])
1307 out.write(hexdigits[(code >> 8) & 0x0000000F])
1308 out.write(hexdigits[(code >> 4) & 0x0000000F])
1309 out.write(hexdigits[code & 0x0000000F])
1310 # Map 16-bit characters to '\uxxxx'
1311 else:
1312 out.write('\\u')
1313 out.write(hexdigits[(code >> 12) & 0x000F])
1314 out.write(hexdigits[(code >> 8) & 0x000F])
1315 out.write(hexdigits[(code >> 4) & 0x000F])
1316 out.write(hexdigits[code & 0x000F])
1317 else:
1318 # Copy characters as-is
1319 out.write(ch)
1320 if ch2 is not None:
1321 out.write(ch2)
1323 out.write(quote)
1325 def __unicode__(self):
1326 return self.proxyval(set())
1328 def __str__(self):
1329 # In Python 3, everything is unicode (including attributes of e.g.
1330 # code objects, such as function names). The Python 2 debugger code
1331 # uses PyUnicodePtr objects to format strings etc, whereas with a
1332 # Python 2 debuggee we'd get PyStringObjectPtr instances with __str__.
1333 # Be compatible with that.
1334 return unicode(self).encode('UTF-8')
1336 def int_from_int(gdbval):
1337 return int(str(gdbval))
1340 def stringify(val):
1341 # TODO: repr() puts everything on one line; pformat can be nicer, but
1342 # can lead to v.long results; this function isolates the choice
1343 if True:
1344 return repr(val)
1345 else:
1346 from pprint import pformat
1347 return pformat(val)
1350 class PyObjectPtrPrinter:
1351 "Prints a (PyObject*)"
1353 def __init__ (self, gdbval):
1354 self.gdbval = gdbval
1356 def to_string (self):
1357 pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval)
1358 if True:
1359 return pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1360 else:
1361 # Generate full proxy value then stringify it.
1362 # Doing so could be expensive
1363 proxyval = pyop.proxyval(set())
1364 return stringify(proxyval)
1366 def pretty_printer_lookup(gdbval):
1367 type = gdbval.type.unqualified()
1368 if type.code == gdb.TYPE_CODE_PTR:
1369 type = type.target().unqualified()
1370 if str(type) in all_pretty_typenames:
1371 return PyObjectPtrPrinter(gdbval)
1374 During development, I've been manually invoking the code in this way:
1375 (gdb) python
1377 import sys
1378 sys.path.append('/home/david/coding/python-gdb')
1379 import libpython
1382 then reloading it after each edit like this:
1383 (gdb) python reload(libpython)
1385 The following code should ensure that the prettyprinter is registered
1386 if the code is autoloaded by gdb when visiting libpython.so, provided
1387 that this python file is installed to the same path as the library (or its
1388 .debug file) plus a "-gdb.py" suffix, e.g:
1389 /usr/lib/libpython2.6.so.1.0-gdb.py
1390 /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
1392 def register (obj):
1393 if obj == None:
1394 obj = gdb
1396 # Wire up the pretty-printer
1397 obj.pretty_printers.append(pretty_printer_lookup)
1399 register (gdb.current_objfile ())
1401 # Unfortunately, the exact API exposed by the gdb module varies somewhat
1402 # from build to build
1403 # See http://bugs.python.org/issue8279?#msg102276
1405 class Frame(object):
1407 Wrapper for gdb.Frame, adding various methods
1409 def __init__(self, gdbframe):
1410 self._gdbframe = gdbframe
1412 def older(self):
1413 older = self._gdbframe.older()
1414 if older:
1415 return Frame(older)
1416 else:
1417 return None
1419 def newer(self):
1420 newer = self._gdbframe.newer()
1421 if newer:
1422 return Frame(newer)
1423 else:
1424 return None
1426 def select(self):
1427 '''If supported, select this frame and return True; return False if unsupported
1429 Not all builds have a gdb.Frame.select method; seems to be present on Fedora 12
1430 onwards, but absent on Ubuntu buildbot'''
1431 if not hasattr(self._gdbframe, 'select'):
1432 print ('Unable to select frame: '
1433 'this build of gdb does not expose a gdb.Frame.select method')
1434 return False
1435 self._gdbframe.select()
1436 return True
1438 def get_index(self):
1439 '''Calculate index of frame, starting at 0 for the newest frame within
1440 this thread'''
1441 index = 0
1442 # Go down until you reach the newest frame:
1443 iter_frame = self
1444 while iter_frame.newer():
1445 index += 1
1446 iter_frame = iter_frame.newer()
1447 return index
1449 def is_evalframeex(self):
1450 '''Is this a PyEval_EvalFrameEx frame?'''
1451 if self._gdbframe.name() == 'PyEval_EvalFrameEx':
1453 I believe we also need to filter on the inline
1454 struct frame_id.inline_depth, only regarding frames with
1455 an inline depth of 0 as actually being this function
1457 So we reject those with type gdb.INLINE_FRAME
1459 if self._gdbframe.type() == gdb.NORMAL_FRAME:
1460 # We have a PyEval_EvalFrameEx frame:
1461 return True
1463 return False
1465 def read_var(self, varname):
1467 read_var with respect to code blocks (gdbframe.read_var works with
1468 respect to the most recent block)
1470 Apparently this function doesn't work, though, as it seems to read
1471 variables in other frames also sometimes.
1473 block = self._gdbframe.block()
1474 var = None
1476 while block and var is None:
1477 try:
1478 var = self._gdbframe.read_var(varname, block)
1479 except ValueError:
1480 pass
1482 block = block.superblock
1484 return var
1486 def get_pyop(self):
1487 try:
1488 # self.read_var does not always work properly, so select our frame
1489 # and restore the previously selected frame
1490 selected_frame = gdb.selected_frame()
1491 self._gdbframe.select()
1492 f = gdb.parse_and_eval('f')
1493 selected_frame.select()
1494 except RuntimeError:
1495 return None
1496 else:
1497 return PyFrameObjectPtr.from_pyobject_ptr(f)
1499 @classmethod
1500 def get_selected_frame(cls):
1501 _gdbframe = gdb.selected_frame()
1502 if _gdbframe:
1503 return Frame(_gdbframe)
1504 return None
1506 @classmethod
1507 def get_selected_python_frame(cls):
1508 '''Try to obtain the Frame for the python code in the selected frame,
1509 or None'''
1510 frame = cls.get_selected_frame()
1512 while frame:
1513 if frame.is_evalframeex():
1514 return frame
1515 frame = frame.older()
1517 # Not found:
1518 return None
1520 def print_summary(self):
1521 if self.is_evalframeex():
1522 pyop = self.get_pyop()
1523 if pyop:
1524 line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
1525 write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line))
1526 sys.stdout.write(pyop.current_line())
1527 else:
1528 sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index())
1529 else:
1530 sys.stdout.write('#%i\n' % self.get_index())
1532 class PyList(gdb.Command):
1533 '''List the current Python source code, if any
1536 py-list START
1537 to list at a different line number within the python source.
1540 py-list START, END
1541 to list a specific range of lines within the python source.
1544 def __init__(self):
1545 gdb.Command.__init__ (self,
1546 "py-list",
1547 gdb.COMMAND_FILES,
1548 gdb.COMPLETE_NONE)
1551 def invoke(self, args, from_tty):
1552 import re
1554 start = None
1555 end = None
1557 m = re.match(r'\s*(\d+)\s*', args)
1558 if m:
1559 start = int(m.group(0))
1560 end = start + 10
1562 m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args)
1563 if m:
1564 start, end = map(int, m.groups())
1566 frame = Frame.get_selected_python_frame()
1567 if not frame:
1568 print 'Unable to locate python frame'
1569 return
1571 pyop = frame.get_pyop()
1572 if not pyop:
1573 print 'Unable to read information on python frame'
1574 return
1576 filename = pyop.filename()
1577 lineno = pyop.current_line_num()
1579 if start is None:
1580 start = lineno - 5
1581 end = lineno + 5
1583 if start<1:
1584 start = 1
1586 with open(os_fsencode(filename), 'r') as f:
1587 all_lines = f.readlines()
1588 # start and end are 1-based, all_lines is 0-based;
1589 # so [start-1:end] as a python slice gives us [start, end] as a
1590 # closed interval
1591 for i, line in enumerate(all_lines[start-1:end]):
1592 linestr = str(i+start)
1593 # Highlight current line:
1594 if i + start == lineno:
1595 linestr = '>' + linestr
1596 sys.stdout.write('%4s %s' % (linestr, line))
1599 # ...and register the command:
1600 PyList()
1602 def move_in_stack(move_up):
1603 '''Move up or down the stack (for the py-up/py-down command)'''
1604 frame = Frame.get_selected_python_frame()
1605 while frame:
1606 if move_up:
1607 iter_frame = frame.older()
1608 else:
1609 iter_frame = frame.newer()
1611 if not iter_frame:
1612 break
1614 if iter_frame.is_evalframeex():
1615 # Result:
1616 if iter_frame.select():
1617 iter_frame.print_summary()
1618 return
1620 frame = iter_frame
1622 if move_up:
1623 print 'Unable to find an older python frame'
1624 else:
1625 print 'Unable to find a newer python frame'
1627 class PyUp(gdb.Command):
1628 'Select and print the python stack frame that called this one (if any)'
1629 def __init__(self):
1630 gdb.Command.__init__ (self,
1631 "py-up",
1632 gdb.COMMAND_STACK,
1633 gdb.COMPLETE_NONE)
1636 def invoke(self, args, from_tty):
1637 move_in_stack(move_up=True)
1639 class PyDown(gdb.Command):
1640 'Select and print the python stack frame called by this one (if any)'
1641 def __init__(self):
1642 gdb.Command.__init__ (self,
1643 "py-down",
1644 gdb.COMMAND_STACK,
1645 gdb.COMPLETE_NONE)
1648 def invoke(self, args, from_tty):
1649 move_in_stack(move_up=False)
1651 # Not all builds of gdb have gdb.Frame.select
1652 if hasattr(gdb.Frame, 'select'):
1653 PyUp()
1654 PyDown()
1656 class PyBacktrace(gdb.Command):
1657 'Display the current python frame and all the frames within its call stack (if any)'
1658 def __init__(self):
1659 gdb.Command.__init__ (self,
1660 "py-bt",
1661 gdb.COMMAND_STACK,
1662 gdb.COMPLETE_NONE)
1665 def invoke(self, args, from_tty):
1666 frame = Frame.get_selected_python_frame()
1667 while frame:
1668 if frame.is_evalframeex():
1669 frame.print_summary()
1670 frame = frame.older()
1672 PyBacktrace()
1674 class PyPrint(gdb.Command):
1675 'Look up the given python variable name, and print it'
1676 def __init__(self):
1677 gdb.Command.__init__ (self,
1678 "py-print",
1679 gdb.COMMAND_DATA,
1680 gdb.COMPLETE_NONE)
1683 def invoke(self, args, from_tty):
1684 name = str(args)
1686 frame = Frame.get_selected_python_frame()
1687 if not frame:
1688 print 'Unable to locate python frame'
1689 return
1691 pyop_frame = frame.get_pyop()
1692 if not pyop_frame:
1693 print 'Unable to read information on python frame'
1694 return
1696 pyop_var, scope = pyop_frame.get_var_by_name(name)
1698 if pyop_var:
1699 print ('%s %r = %s'
1700 % (scope,
1701 name,
1702 pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
1703 else:
1704 print '%r not found' % name
1706 PyPrint()
1708 class PyLocals(gdb.Command):
1709 'Look up the given python variable name, and print it'
1711 def invoke(self, args, from_tty):
1712 name = str(args)
1714 frame = Frame.get_selected_python_frame()
1715 if not frame:
1716 print 'Unable to locate python frame'
1717 return
1719 pyop_frame = frame.get_pyop()
1720 if not pyop_frame:
1721 print 'Unable to read information on python frame'
1722 return
1724 namespace = self.get_namespace(pyop_frame)
1725 namespace = [(name.proxyval(set()), val) for name, val in namespace]
1727 if namespace:
1728 name, val = max(namespace, key=lambda (name, val): len(name))
1729 max_name_length = len(name)
1731 for name, pyop_value in namespace:
1732 value = pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)
1733 print ('%-*s = %s' % (max_name_length, name, value))
1735 def get_namespace(self, pyop_frame):
1736 return pyop_frame.iter_locals()
1739 class PyGlobals(PyLocals):
1740 'List all the globals in the currently select Python frame'
1742 def get_namespace(self, pyop_frame):
1743 return pyop_frame.iter_globals()
1746 PyLocals("py-locals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
1747 PyGlobals("py-globals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
1750 class PyNameEquals(gdb.Function):
1752 def _get_pycurframe_attr(self, attr):
1753 frame = Frame(gdb.selected_frame())
1754 if frame.is_evalframeex():
1755 pyframe = frame.get_pyop()
1756 if pyframe is None:
1757 warnings.warn("Use a Python debug build, Python breakpoints "
1758 "won't work otherwise.")
1759 return None
1761 return getattr(pyframe, attr).proxyval(set())
1763 return None
1765 def invoke(self, funcname):
1766 attr = self._get_pycurframe_attr('co_name')
1767 return attr is not None and attr == funcname.string()
1769 PyNameEquals("pyname_equals")
1772 class PyModEquals(PyNameEquals):
1774 def invoke(self, modname):
1775 attr = self._get_pycurframe_attr('co_filename')
1776 if attr is not None:
1777 filename, ext = os.path.splitext(os.path.basename(attr))
1778 return filename == modname.string()
1779 return False
1781 PyModEquals("pymod_equals")
1784 class PyBreak(gdb.Command):
1786 Set a Python breakpoint. Examples:
1788 Break on any function or method named 'func' in module 'modname'
1790 py-break modname.func
1792 Break on any function or method named 'func'
1794 py-break func
1797 def invoke(self, funcname, from_tty):
1798 if '.' in funcname:
1799 modname, dot, funcname = funcname.rpartition('.')
1800 cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname,
1801 modname)
1802 else:
1803 cond = '$pyname_equals("%s")' % funcname
1805 gdb.execute('break PyEval_EvalFrameEx if ' + cond)
1807 PyBreak("py-break", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE)
1810 class _LoggingState(object):
1812 State that helps to provide a reentrant gdb.execute() function.
1815 def __init__(self):
1816 self.fd, self.filename = tempfile.mkstemp()
1817 self.file = os.fdopen(self.fd, 'r+')
1818 _execute("set logging file %s" % self.filename)
1819 self.file_position_stack = []
1821 atexit.register(os.close, self.fd)
1822 atexit.register(os.remove, self.filename)
1824 def __enter__(self):
1825 if not self.file_position_stack:
1826 _execute("set logging redirect on")
1827 _execute("set logging on")
1828 _execute("set pagination off")
1830 self.file_position_stack.append(os.fstat(self.fd).st_size)
1831 return self
1833 def getoutput(self):
1834 gdb.flush()
1835 self.file.seek(self.file_position_stack[-1])
1836 result = self.file.read()
1837 return result
1839 def __exit__(self, exc_type, exc_val, tb):
1840 startpos = self.file_position_stack.pop()
1841 self.file.seek(startpos)
1842 self.file.truncate()
1843 if not self.file_position_stack:
1844 _execute("set logging off")
1845 _execute("set logging redirect off")
1846 _execute("set pagination on")
1849 def execute(command, from_tty=False, to_string=False):
1851 Replace gdb.execute() with this function and have it accept a 'to_string'
1852 argument (new in 7.2). Have it properly capture stderr also. Ensure
1853 reentrancy.
1855 if to_string:
1856 with _logging_state as state:
1857 _execute(command, from_tty)
1858 return state.getoutput()
1859 else:
1860 _execute(command, from_tty)
1863 _execute = gdb.execute
1864 gdb.execute = execute
1865 _logging_state = _LoggingState()
1868 def get_selected_inferior():
1870 Return the selected inferior in gdb.
1872 # Woooh, another bug in gdb! Is there an end in sight?
1873 # http://sourceware.org/bugzilla/show_bug.cgi?id=12212
1874 return gdb.inferiors()[0]
1876 selected_thread = gdb.selected_thread()
1878 for inferior in gdb.inferiors():
1879 for thread in inferior.threads():
1880 if thread == selected_thread:
1881 return inferior
1883 def source_gdb_script(script_contents, to_string=False):
1885 Source a gdb script with script_contents passed as a string. This is useful
1886 to provide defines for py-step and py-next to make them repeatable (this is
1887 not possible with gdb.execute()). See
1888 http://sourceware.org/bugzilla/show_bug.cgi?id=12216
1890 fd, filename = tempfile.mkstemp()
1891 f = os.fdopen(fd, 'w')
1892 f.write(script_contents)
1893 f.close()
1894 gdb.execute("source %s" % filename, to_string=to_string)
1895 os.remove(filename)
1897 def register_defines():
1898 source_gdb_script(textwrap.dedent("""\
1899 define py-step
1900 -py-step
1903 define py-next
1904 -py-next
1907 document py-step
1911 document py-next
1914 """) % (PyStep.__doc__, PyNext.__doc__))
1917 def stackdepth(frame):
1918 "Tells the stackdepth of a gdb frame."
1919 depth = 0
1920 while frame:
1921 frame = frame.older()
1922 depth += 1
1924 return depth
1926 class ExecutionControlCommandBase(gdb.Command):
1928 Superclass for language specific execution control. Language specific
1929 features should be implemented by lang_info using the LanguageInfo
1930 interface. 'name' is the name of the command.
1933 def __init__(self, name, lang_info):
1934 super(ExecutionControlCommandBase, self).__init__(
1935 name, gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE)
1936 self.lang_info = lang_info
1938 def install_breakpoints(self):
1939 all_locations = itertools.chain(
1940 self.lang_info.static_break_functions(),
1941 self.lang_info.runtime_break_functions())
1943 for location in all_locations:
1944 result = gdb.execute('break %s' % location, to_string=True)
1945 yield re.search(r'Breakpoint (\d+)', result).group(1)
1947 def delete_breakpoints(self, breakpoint_list):
1948 for bp in breakpoint_list:
1949 gdb.execute("delete %s" % bp)
1951 def filter_output(self, result):
1952 reflags = re.MULTILINE
1954 output_on_halt = [
1955 (r'^Program received signal .*', reflags|re.DOTALL),
1956 (r'.*[Ww]arning.*', 0),
1957 (r'^Program exited .*', reflags),
1960 output_always = [
1961 # output when halting on a watchpoint
1962 (r'^(Old|New) value = .*', reflags),
1963 # output from the 'display' command
1964 (r'^\d+: \w+ = .*', reflags),
1967 def filter_output(regexes):
1968 output = []
1969 for regex, flags in regexes:
1970 for match in re.finditer(regex, result, flags):
1971 output.append(match.group(0))
1973 return '\n'.join(output)
1975 # Filter the return value output of the 'finish' command
1976 match_finish = re.search(r'^Value returned is \$\d+ = (.*)', result,
1977 re.MULTILINE)
1978 if match_finish:
1979 finish_output = 'Value returned: %s\n' % match_finish.group(1)
1980 else:
1981 finish_output = ''
1983 return (filter_output(output_on_halt),
1984 finish_output + filter_output(output_always))
1987 def stopped(self):
1988 return get_selected_inferior().pid == 0
1990 def finish_executing(self, result):
1992 After doing some kind of code running in the inferior, print the line
1993 of source code or the result of the last executed gdb command (passed
1994 in as the `result` argument).
1996 output_on_halt, output_always = self.filter_output(result)
1998 if self.stopped():
1999 print output_always
2000 print output_on_halt
2001 else:
2002 frame = gdb.selected_frame()
2003 source_line = self.lang_info.get_source_line(frame)
2004 if self.lang_info.is_relevant_function(frame):
2005 raised_exception = self.lang_info.exc_info(frame)
2006 if raised_exception:
2007 print raised_exception
2009 if source_line:
2010 if output_always.rstrip():
2011 print output_always.rstrip()
2012 print source_line
2013 else:
2014 print result
2016 def _finish(self):
2018 Execute until the function returns (or until something else makes it
2019 stop)
2021 if gdb.selected_frame().older() is not None:
2022 return gdb.execute('finish', to_string=True)
2023 else:
2024 # outermost frame, continue
2025 return gdb.execute('cont', to_string=True)
2027 def _finish_frame(self):
2029 Execute until the function returns to a relevant caller.
2031 while True:
2032 result = self._finish()
2034 try:
2035 frame = gdb.selected_frame()
2036 except RuntimeError:
2037 break
2039 hitbp = re.search(r'Breakpoint (\d+)', result)
2040 is_relevant = self.lang_info.is_relevant_function(frame)
2041 if hitbp or is_relevant or self.stopped():
2042 break
2044 return result
2046 def finish(self, *args):
2047 "Implements the finish command."
2048 result = self._finish_frame()
2049 self.finish_executing(result)
2051 def step(self, stepinto, stepover_command='next'):
2053 Do a single step or step-over. Returns the result of the last gdb
2054 command that made execution stop.
2056 This implementation, for stepping, sets (conditional) breakpoints for
2057 all functions that are deemed relevant. It then does a step over until
2058 either something halts execution, or until the next line is reached.
2060 If, however, stepover_command is given, it should be a string gdb
2061 command that continues execution in some way. The idea is that the
2062 caller has set a (conditional) breakpoint or watchpoint that can work
2063 more efficiently than the step-over loop. For Python this means setting
2064 a watchpoint for f->f_lasti, which means we can then subsequently
2065 "finish" frames.
2066 We want f->f_lasti instead of f->f_lineno, because the latter only
2067 works properly with local trace functions, see
2068 PyFrameObjectPtr.current_line_num and PyFrameObjectPtr.addr2line.
2070 if stepinto:
2071 breakpoint_list = list(self.install_breakpoints())
2073 beginframe = gdb.selected_frame()
2075 if self.lang_info.is_relevant_function(beginframe):
2076 # If we start in a relevant frame, initialize stuff properly. If
2077 # we don't start in a relevant frame, the loop will halt
2078 # immediately. So don't call self.lang_info.lineno() as it may
2079 # raise for irrelevant frames.
2080 beginline = self.lang_info.lineno(beginframe)
2082 if not stepinto:
2083 depth = stackdepth(beginframe)
2085 newframe = beginframe
2087 while True:
2088 if self.lang_info.is_relevant_function(newframe):
2089 result = gdb.execute(stepover_command, to_string=True)
2090 else:
2091 result = self._finish_frame()
2093 if self.stopped():
2094 break
2096 newframe = gdb.selected_frame()
2097 is_relevant_function = self.lang_info.is_relevant_function(newframe)
2098 try:
2099 framename = newframe.name()
2100 except RuntimeError:
2101 framename = None
2103 m = re.search(r'Breakpoint (\d+)', result)
2104 if m:
2105 if is_relevant_function and m.group(1) in breakpoint_list:
2106 # although we hit a breakpoint, we still need to check
2107 # that the function, in case hit by a runtime breakpoint,
2108 # is in the right context
2109 break
2111 if newframe != beginframe:
2112 # new function
2114 if not stepinto:
2115 # see if we returned to the caller
2116 newdepth = stackdepth(newframe)
2117 is_relevant_function = (newdepth < depth and
2118 is_relevant_function)
2120 if is_relevant_function:
2121 break
2122 else:
2123 # newframe equals beginframe, check for a difference in the
2124 # line number
2125 lineno = self.lang_info.lineno(newframe)
2126 if lineno and lineno != beginline:
2127 break
2129 if stepinto:
2130 self.delete_breakpoints(breakpoint_list)
2132 self.finish_executing(result)
2134 def run(self, args, from_tty):
2135 self.finish_executing(gdb.execute('run ' + args, to_string=True))
2137 def cont(self, *args):
2138 self.finish_executing(gdb.execute('cont', to_string=True))
2141 class LanguageInfo(object):
2143 This class defines the interface that ExecutionControlCommandBase needs to
2144 provide language-specific execution control.
2146 Classes that implement this interface should implement:
2148 lineno(frame)
2149 Tells the current line number (only called for a relevant frame).
2150 If lineno is a false value it is not checked for a difference.
2152 is_relevant_function(frame)
2153 tells whether we care about frame 'frame'
2155 get_source_line(frame)
2156 get the line of source code for the current line (only called for a
2157 relevant frame). If the source code cannot be retrieved this
2158 function should return None
2160 exc_info(frame) -- optional
2161 tells whether an exception was raised, if so, it should return a
2162 string representation of the exception value, None otherwise.
2164 static_break_functions()
2165 returns an iterable of function names that are considered relevant
2166 and should halt step-into execution. This is needed to provide a
2167 performing step-into
2169 runtime_break_functions() -- optional
2170 list of functions that we should break into depending on the
2171 context
2174 def exc_info(self, frame):
2175 "See this class' docstring."
2177 def runtime_break_functions(self):
2179 Implement this if the list of step-into functions depends on the
2180 context.
2182 return ()
2184 class PythonInfo(LanguageInfo):
2186 def pyframe(self, frame):
2187 pyframe = Frame(frame).get_pyop()
2188 if pyframe:
2189 return pyframe
2190 else:
2191 raise gdb.RuntimeError(
2192 "Unable to find the Python frame, run your code with a debug "
2193 "build (configure with --with-pydebug or compile with -g).")
2195 def lineno(self, frame):
2196 return self.pyframe(frame).current_line_num()
2198 def is_relevant_function(self, frame):
2199 return Frame(frame).is_evalframeex()
2201 def get_source_line(self, frame):
2202 try:
2203 pyframe = self.pyframe(frame)
2204 return '%4d %s' % (pyframe.current_line_num(),
2205 pyframe.current_line().rstrip())
2206 except IOError, e:
2207 return None
2209 def exc_info(self, frame):
2210 try:
2211 tstate = frame.read_var('tstate').dereference()
2212 if gdb.parse_and_eval('tstate->frame == f'):
2213 # tstate local variable initialized, check for an exception
2214 inf_type = tstate['curexc_type']
2215 inf_value = tstate['curexc_value']
2217 if inf_type:
2218 return 'An exception was raised: %s' % (inf_value,)
2219 except (ValueError, RuntimeError), e:
2220 # Could not read the variable tstate or it's memory, it's ok
2221 pass
2223 def static_break_functions(self):
2224 yield 'PyEval_EvalFrameEx'
2227 class PythonStepperMixin(object):
2229 Make this a mixin so CyStep can also inherit from this and use a
2230 CythonCodeStepper at the same time.
2233 def python_step(self, stepinto):
2235 Set a watchpoint on the Python bytecode instruction pointer and try
2236 to finish the frame
2238 output = gdb.execute('watch f->f_lasti', to_string=True)
2239 watchpoint = int(re.search(r'[Ww]atchpoint (\d+):', output).group(1))
2240 self.step(stepinto=stepinto, stepover_command='finish')
2241 gdb.execute('delete %s' % watchpoint)
2244 class PyStep(ExecutionControlCommandBase, PythonStepperMixin):
2245 "Step through Python code."
2247 stepinto = True
2249 def invoke(self, args, from_tty):
2250 self.python_step(stepinto=self.stepinto)
2252 class PyNext(PyStep):
2253 "Step-over Python code."
2255 stepinto = False
2257 class PyFinish(ExecutionControlCommandBase):
2258 "Execute until function returns to a caller."
2260 invoke = ExecutionControlCommandBase.finish
2262 class PyRun(ExecutionControlCommandBase):
2263 "Run the program."
2265 invoke = ExecutionControlCommandBase.run
2267 class PyCont(ExecutionControlCommandBase):
2269 invoke = ExecutionControlCommandBase.cont
2272 def _pointervalue(gdbval):
2274 Return the value of the pionter as a Python int.
2276 gdbval.type must be a pointer type
2278 # don't convert with int() as it will raise a RuntimeError
2279 if gdbval.address is not None:
2280 return long(gdbval.address)
2281 else:
2282 # the address attribute is None sometimes, in which case we can
2283 # still convert the pointer to an int
2284 return long(gdbval)
2286 def pointervalue(gdbval):
2287 pointer = _pointervalue(gdbval)
2288 try:
2289 if pointer < 0:
2290 raise gdb.GdbError("Negative pointer value, presumably a bug "
2291 "in gdb, aborting.")
2292 except RuntimeError:
2293 # work around yet another bug in gdb where you get random behaviour
2294 # and tracebacks
2295 pass
2297 return pointer
2299 def get_inferior_unicode_postfix():
2300 try:
2301 gdb.parse_and_eval('PyUnicode_FromEncodedObject')
2302 except RuntimeError:
2303 try:
2304 gdb.parse_and_eval('PyUnicodeUCS2_FromEncodedObject')
2305 except RuntimeError:
2306 return 'UCS4'
2307 else:
2308 return 'UCS2'
2309 else:
2310 return ''
2312 class PythonCodeExecutor(object):
2314 Py_single_input = 256
2315 Py_file_input = 257
2316 Py_eval_input = 258
2318 def malloc(self, size):
2319 chunk = (gdb.parse_and_eval("(void *) malloc((size_t) %d)" % size))
2321 pointer = pointervalue(chunk)
2322 if pointer == 0:
2323 raise gdb.GdbError("No memory could be allocated in the inferior.")
2325 return pointer
2327 def alloc_string(self, string):
2328 pointer = self.malloc(len(string))
2329 get_selected_inferior().write_memory(pointer, string)
2331 return pointer
2333 def alloc_pystring(self, string):
2334 stringp = self.alloc_string(string)
2335 PyString_FromStringAndSize = 'PyString_FromStringAndSize'
2337 try:
2338 gdb.parse_and_eval(PyString_FromStringAndSize)
2339 except RuntimeError:
2340 # Python 3
2341 PyString_FromStringAndSize = ('PyUnicode%s_FromStringAndSize' %
2342 (get_inferior_unicode_postfix(),))
2344 try:
2345 result = gdb.parse_and_eval(
2346 '(PyObject *) %s((char *) %d, (size_t) %d)' % (
2347 PyString_FromStringAndSize, stringp, len(string)))
2348 finally:
2349 self.free(stringp)
2351 pointer = pointervalue(result)
2352 if pointer == 0:
2353 raise gdb.GdbError("Unable to allocate Python string in "
2354 "the inferior.")
2356 return pointer
2358 def free(self, pointer):
2359 gdb.parse_and_eval("free((void *) %d)" % pointer)
2361 def incref(self, pointer):
2362 "Increment the reference count of a Python object in the inferior."
2363 gdb.parse_and_eval('Py_IncRef((PyObject *) %d)' % pointer)
2365 def xdecref(self, pointer):
2366 "Decrement the reference count of a Python object in the inferior."
2367 # Py_DecRef is like Py_XDECREF, but a function. So we don't have
2368 # to check for NULL. This should also decref all our allocated
2369 # Python strings.
2370 gdb.parse_and_eval('Py_DecRef((PyObject *) %d)' % pointer)
2372 def evalcode(self, code, input_type, global_dict=None, local_dict=None):
2374 Evaluate python code `code` given as a string in the inferior and
2375 return the result as a gdb.Value. Returns a new reference in the
2376 inferior.
2378 Of course, executing any code in the inferior may be dangerous and may
2379 leave the debuggee in an unsafe state or terminate it alltogether.
2381 if '\0' in code:
2382 raise gdb.GdbError("String contains NUL byte.")
2384 code += '\0'
2386 pointer = self.alloc_string(code)
2388 globalsp = pointervalue(global_dict)
2389 localsp = pointervalue(local_dict)
2391 if globalsp == 0 or localsp == 0:
2392 raise gdb.GdbError("Unable to obtain or create locals or globals.")
2394 code = """
2395 PyRun_String(
2396 (char *) %(code)d,
2397 (int) %(start)d,
2398 (PyObject *) %(globals)s,
2399 (PyObject *) %(locals)d)
2400 """ % dict(code=pointer, start=input_type,
2401 globals=globalsp, locals=localsp)
2403 with FetchAndRestoreError():
2404 try:
2405 pyobject_return_value = gdb.parse_and_eval(code)
2406 finally:
2407 self.free(pointer)
2409 return pyobject_return_value
2411 class FetchAndRestoreError(PythonCodeExecutor):
2413 Context manager that fetches the error indicator in the inferior and
2414 restores it on exit.
2417 def __init__(self):
2418 self.sizeof_PyObjectPtr = gdb.lookup_type('PyObject').pointer().sizeof
2419 self.pointer = self.malloc(self.sizeof_PyObjectPtr * 3)
2421 type = self.pointer
2422 value = self.pointer + self.sizeof_PyObjectPtr
2423 traceback = self.pointer + self.sizeof_PyObjectPtr * 2
2425 self.errstate = type, value, traceback
2427 def __enter__(self):
2428 gdb.parse_and_eval("PyErr_Fetch(%d, %d, %d)" % self.errstate)
2430 def __exit__(self, *args):
2431 if gdb.parse_and_eval("(int) PyErr_Occurred()"):
2432 gdb.parse_and_eval("PyErr_Print()")
2434 pyerr_restore = ("PyErr_Restore("
2435 "(PyObject *) *%d,"
2436 "(PyObject *) *%d,"
2437 "(PyObject *) *%d)")
2439 try:
2440 gdb.parse_and_eval(pyerr_restore % self.errstate)
2441 finally:
2442 self.free(self.pointer)
2445 class FixGdbCommand(gdb.Command):
2447 def __init__(self, command, actual_command):
2448 super(FixGdbCommand, self).__init__(command, gdb.COMMAND_DATA,
2449 gdb.COMPLETE_NONE)
2450 self.actual_command = actual_command
2452 def fix_gdb(self):
2454 It seems that invoking either 'cy exec' and 'py-exec' work perfectly
2455 fine, but after this gdb's python API is entirely broken.
2456 Maybe some uncleared exception value is still set?
2457 sys.exc_clear() didn't help. A demonstration:
2459 (gdb) cy exec 'hello'
2460 'hello'
2461 (gdb) python gdb.execute('cont')
2462 RuntimeError: Cannot convert value to int.
2463 Error while executing Python code.
2464 (gdb) python gdb.execute('cont')
2465 [15148 refs]
2467 Program exited normally.
2469 warnings.filterwarnings('ignore', r'.*', RuntimeWarning,
2470 re.escape(__name__))
2471 try:
2472 long(gdb.parse_and_eval("(void *) 0")) == 0
2473 except RuntimeError:
2474 pass
2475 # warnings.resetwarnings()
2477 def invoke(self, args, from_tty):
2478 self.fix_gdb()
2479 try:
2480 gdb.execute('%s %s' % (self.actual_command, args))
2481 except RuntimeError, e:
2482 raise gdb.GdbError(str(e))
2483 self.fix_gdb()
2486 def _evalcode_python(executor, code, input_type):
2488 Execute Python code in the most recent stack frame.
2490 global_dict = gdb.parse_and_eval('PyEval_GetGlobals()')
2491 local_dict = gdb.parse_and_eval('PyEval_GetLocals()')
2493 if (pointervalue(global_dict) == 0 or pointervalue(local_dict) == 0):
2494 raise gdb.GdbError("Unable to find the locals or globals of the "
2495 "most recent Python function (relative to the "
2496 "selected frame).")
2498 return executor.evalcode(code, input_type, global_dict, local_dict)
2500 class PyExec(gdb.Command):
2502 def readcode(self, expr):
2503 if expr:
2504 return expr, PythonCodeExecutor.Py_single_input
2505 else:
2506 lines = []
2507 while True:
2508 try:
2509 line = raw_input('>')
2510 except EOFError:
2511 break
2512 else:
2513 if line.rstrip() == 'end':
2514 break
2516 lines.append(line)
2518 return '\n'.join(lines), PythonCodeExecutor.Py_file_input
2520 def invoke(self, expr, from_tty):
2521 expr, input_type = self.readcode(expr)
2522 executor = PythonCodeExecutor()
2523 executor.xdecref(_evalcode_python(executor, input_type, global_dict,
2524 local_dict))
2527 gdb.execute('set breakpoint pending on')
2529 if hasattr(gdb, 'GdbError'):
2530 # Wrap py-step and py-next in gdb defines to make them repeatable.
2531 py_step = PyStep('-py-step', PythonInfo())
2532 py_next = PyNext('-py-next', PythonInfo())
2533 register_defines()
2534 py_finish = PyFinish('py-finish', PythonInfo())
2535 py_run = PyRun('py-run', PythonInfo())
2536 py_cont = PyCont('py-cont', PythonInfo())
2538 py_exec = FixGdbCommand('py-exec', '-py-exec')
2539 _py_exec = PyExec("-py-exec", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
2540 else:
2541 warnings.warn("Use gdb 7.2 or higher to use the py-exec command.")