Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Private Attributes
libpython.PyFrameObjectPtr Class Reference
Inheritance diagram for libpython.PyFrameObjectPtr:
Inheritance graph
[legend]
Collaboration diagram for libpython.PyFrameObjectPtr:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def iter_locals
def iter_globals
def iter_builtins
def get_var_by_name
def filename
def current_line_num
def current_line
def write_repr
def print_traceback
def field
def pyop_field
def write_field_repr
def get_truncated_repr
def type
def is_null
def is_optimized_out
def safe_tp_name
def proxyval
def subclass_from_type
def from_pyobject_ptr
def get_gdb_type
def as_address

Public Attributes

 co
 co_name
 co_filename
 f_lineno
 f_lasti
 co_nlocals
 co_varnames
 tp_name
 address
_PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt
struct _typeobjectob_type

Static Private Attributes

string _typename = 'PyFrameObject'

Detailed Description

Definition at line 806 of file libpython.py.


Constructor & Destructor Documentation

def libpython.PyFrameObjectPtr.__init__ (   self,
  gdbval,
  cast_to 
)

Reimplemented from libpython.PyObjectPtr.

Definition at line 809 of file libpython.py.

00809 
00810     def __init__(self, gdbval, cast_to):
00811         PyObjectPtr.__init__(self, gdbval, cast_to)
00812 
00813         if not self.is_optimized_out():
00814             self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
00815             self.co_name = self.co.pyop_field('co_name')
00816             self.co_filename = self.co.pyop_field('co_filename')
00817 
00818             self.f_lineno = int_from_int(self.field('f_lineno'))
00819             self.f_lasti = int_from_int(self.field('f_lasti'))
00820             self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
00821             self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))

Here is the call graph for this function:

Here is the caller graph for this function:


Member Function Documentation

def libpython.PyObjectPtr.as_address (   self) [inherited]

Definition at line 379 of file libpython.py.

00379 
00380     def as_address(self):
00381         return long(self._gdbval)

Here is the caller graph for this function:

Get the text of the current source line as a string, with a trailing
newline character

Definition at line 902 of file libpython.py.

00902 
00903     def current_line(self):
00904         '''Get the text of the current source line as a string, with a trailing
00905         newline character'''
00906         if self.is_optimized_out():
00907             return '(frame information optimized out)'
00908         filename = self.filename()
00909         try:
00910             f = open(os_fsencode(filename), 'r')
00911         except IOError:
00912             return None
00913         with f:
00914             all_lines = f.readlines()
00915             # Convert from 1-based current_line_num to 0-based list offset:
00916             return all_lines[self.current_line_num()-1]

Here is the call graph for this function:

Get current line number as an integer (1-based)

Translated from PyFrame_GetLineNumber and PyCode_Addr2Line

See Objects/lnotab_notes.txt

Definition at line 883 of file libpython.py.

00883 
00884     def current_line_num(self):
00885         '''Get current line number as an integer (1-based)
00886 
00887         Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
00888 
00889         See Objects/lnotab_notes.txt
00890         '''
00891         if self.is_optimized_out():
00892             return None
00893         f_trace = self.field('f_trace')
00894         if long(f_trace) != 0:
00895             # we have a non-NULL f_trace:
00896             return self.f_lineno
00897         else:
00898             #try:
00899             return self.co.addr2line(self.f_lasti)
00900             #except ValueError:
00901             #    return self.f_lineno

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.field (   self,
  name 
) [inherited]
Get the gdb.Value for the given field within the PyObject, coping with
some python 2 versus python 3 differences.

Various libpython types are defined using the "PyObject_HEAD" and
"PyObject_VAR_HEAD" macros.

In Python 2, this these are defined so that "ob_type" and (for a var
object) "ob_size" are fields of the type in question.

In Python 3, this is defined as an embedded PyVarObject type thus:
   PyVarObject ob_base;
so that the "ob_size" field is located insize the "ob_base" field, and
the "ob_type" is most easily accessed by casting back to a (PyObject*).

Definition at line 157 of file libpython.py.

00157 
00158     def field(self, name):
00159         '''
00160         Get the gdb.Value for the given field within the PyObject, coping with
00161         some python 2 versus python 3 differences.
00162 
00163         Various libpython types are defined using the "PyObject_HEAD" and
00164         "PyObject_VAR_HEAD" macros.
00165 
00166         In Python 2, this these are defined so that "ob_type" and (for a var
00167         object) "ob_size" are fields of the type in question.
00168 
00169         In Python 3, this is defined as an embedded PyVarObject type thus:
00170            PyVarObject ob_base;
00171         so that the "ob_size" field is located insize the "ob_base" field, and
00172         the "ob_type" is most easily accessed by casting back to a (PyObject*).
00173         '''
00174         if self.is_null():
00175             raise NullPyObjectPtr(self)
00176 
00177         if name == 'ob_type':
00178             pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type())
00179             return pyo_ptr.dereference()[name]
00180 
00181         if name == 'ob_size':
00182             pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type())
00183             return pyo_ptr.dereference()[name]
00184 
00185         # General case: look it up inside the object:
00186         return self._gdbval.dereference()[name]

Here is the call graph for this function:

Here is the caller graph for this function:

Get the path of the current Python source file, as a string

Definition at line 877 of file libpython.py.

00877 
00878     def filename(self):
00879         '''Get the path of the current Python source file, as a string'''
00880         if self.is_optimized_out():
00881             return '(frame information optimized out)'
00882         return self.co_filename.proxyval(set())

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.from_pyobject_ptr (   cls,
  gdbval 
) [inherited]
Try to locate the appropriate derived class dynamically, and cast
the pointer accordingly.

Definition at line 360 of file libpython.py.

00360 
00361     def from_pyobject_ptr(cls, gdbval):
00362         '''
00363         Try to locate the appropriate derived class dynamically, and cast
00364         the pointer accordingly.
00365         '''
00366         try:
00367             p = PyObjectPtr(gdbval)
00368             cls = cls.subclass_from_type(p.type())
00369             return cls(gdbval, cast_to=cls.get_gdb_type())
00370         except RuntimeError:
00371             # Handle any kind of error e.g. NULL ptrs by simply using the base
00372             # class
00373             pass
00374         return cls(gdbval)

def libpython.PyObjectPtr.get_gdb_type (   cls) [inherited]

Definition at line 376 of file libpython.py.

00376 
00377     def get_gdb_type(cls):
00378         return gdb.lookup_type(cls._typename).pointer()

def libpython.PyObjectPtr.get_truncated_repr (   self,
  maxlen 
) [inherited]
Get a repr-like string for the data, but truncate it at "maxlen" bytes
(ending the object graph traversal as soon as you do)

Definition at line 202 of file libpython.py.

00202 
00203     def get_truncated_repr(self, maxlen):
00204         '''
00205         Get a repr-like string for the data, but truncate it at "maxlen" bytes
00206         (ending the object graph traversal as soon as you do)
00207         '''
00208         out = TruncatedStringIO(maxlen)
00209         try:
00210             self.write_repr(out, set())
00211         except StringTruncated:
00212             # Truncation occurred:
00213             return out.getvalue() + '...(truncated)'
00214 
00215         # No truncation occurred:
00216         return out.getvalue()

Here is the call graph for this function:

def libpython.PyFrameObjectPtr.get_var_by_name (   self,
  name 
)
Look for the named local variable, returning a (PyObjectPtr, scope) pair
where scope is a string 'local', 'global', 'builtin'

If not found, return (None, None)

Definition at line 859 of file libpython.py.

00859 
00860     def get_var_by_name(self, name):
00861         '''
00862         Look for the named local variable, returning a (PyObjectPtr, scope) pair
00863         where scope is a string 'local', 'global', 'builtin'
00864 
00865         If not found, return (None, None)
00866         '''
00867         for pyop_name, pyop_value in self.iter_locals():
00868             if name == pyop_name.proxyval(set()):
00869                 return pyop_value, 'local'
00870         for pyop_name, pyop_value in self.iter_globals():
00871             if name == pyop_name.proxyval(set()):
00872                 return pyop_value, 'global'
00873         for pyop_name, pyop_value in self.iter_builtins():
00874             if name == pyop_name.proxyval(set()):
00875                 return pyop_value, 'builtin'
00876         return None, None

Here is the call graph for this function:

def libpython.PyObjectPtr.is_null (   self) [inherited]

Definition at line 220 of file libpython.py.

00220 
00221     def is_null(self):
00222         return 0 == long(self._gdbval)

Here is the caller graph for this function:

def libpython.PyObjectPtr.is_optimized_out (   self) [inherited]
Is the value of the underlying PyObject* visible to the debugger?

This can vary with the precise version of the compiler used to build
Python, and the precise version of gdb.

See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
PyEval_EvalFrameEx's "f"

Definition at line 223 of file libpython.py.

00223 
00224     def is_optimized_out(self):
00225         '''
00226         Is the value of the underlying PyObject* visible to the debugger?
00227 
00228         This can vary with the precise version of the compiler used to build
00229         Python, and the precise version of gdb.
00230 
00231         See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
00232         PyEval_EvalFrameEx's "f"
00233         '''
00234         return self._gdbval.is_optimized_out

Here is the caller graph for this function:

Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
the builtin variables

Definition at line 848 of file libpython.py.

00848 
00849     def iter_builtins(self):
00850         '''
00851         Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
00852         the builtin variables
00853         '''
00854         if self.is_optimized_out():
00855             return
00856 
00857         pyop_builtins = self.pyop_field('f_builtins')
00858         return pyop_builtins.iteritems()

Here is the call graph for this function:

Here is the caller graph for this function:

Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
the global variables of this frame

Definition at line 837 of file libpython.py.

00837 
00838     def iter_globals(self):
00839         '''
00840         Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
00841         the global variables of this frame
00842         '''
00843         if self.is_optimized_out():
00844             return
00845 
00846         pyop_globals = self.pyop_field('f_globals')
00847         return pyop_globals.iteritems()

Here is the call graph for this function:

Here is the caller graph for this function:

Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
the local variables of this frame

Definition at line 822 of file libpython.py.

00822 
00823     def iter_locals(self):
00824         '''
00825         Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
00826         the local variables of this frame
00827         '''
00828         if self.is_optimized_out():
00829             return
00830 
00831         f_localsplus = self.field('f_localsplus')
00832         for i in safe_range(self.co_nlocals):
00833             pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
00834             if not pyop_value.is_null():
00835                 pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
00836                 yield (pyop_name, pyop_value)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 938 of file libpython.py.

00938 
00939     def print_traceback(self):
00940         if self.is_optimized_out():
00941             sys.stdout.write('  (frame information optimized out)\n')
00942         visited = set()
00943         sys.stdout.write('  File "%s", line %i, in %s\n'
00944                   % (self.co_filename.proxyval(visited),
00945                      self.current_line_num(),
00946                      self.co_name.proxyval(visited)))

Here is the call graph for this function:

def libpython.PyObjectPtr.proxyval (   self,
  visited 
) [inherited]
Scrape a value from the inferior process, and try to represent it
within the gdb process, whilst (hopefully) avoiding crashes when
the remote data is corrupt.

Derived classes will override this.

For example, a PyIntObject* with ob_ival 42 in the inferior process
should result in an int(42) in this process.

visited: a set of all gdb.Value pyobject pointers already visited
whilst generating this value (to guard against infinite recursion when
visiting object graphs with loops).  Analogous to Py_ReprEnter and
Py_ReprLeave

Reimplemented in libpython.PyUnicodeObjectPtr, libpython.PyTupleObjectPtr, libpython.PyBytesObjectPtr, libpython.PySetObjectPtr, libpython.PyNoneStructPtr, libpython.PyBoolObjectPtr, libpython.PyLongObjectPtr, libpython.PyListObjectPtr, libpython.PyInstanceObjectPtr, libpython.PyDictObjectPtr, libpython.PyCFunctionObjectPtr, libpython.PyBaseExceptionObjectPtr, and libpython.HeapTypeObjectPtr.

Definition at line 245 of file libpython.py.

00245 
00246     def proxyval(self, visited):
00247         '''
00248         Scrape a value from the inferior process, and try to represent it
00249         within the gdb process, whilst (hopefully) avoiding crashes when
00250         the remote data is corrupt.
00251 
00252         Derived classes will override this.
00253 
00254         For example, a PyIntObject* with ob_ival 42 in the inferior process
00255         should result in an int(42) in this process.
00256 
00257         visited: a set of all gdb.Value pyobject pointers already visited
00258         whilst generating this value (to guard against infinite recursion when
00259         visiting object graphs with loops).  Analogous to Py_ReprEnter and
00260         Py_ReprLeave
00261         '''
00262 
00263         class FakeRepr(object):
00264             """
00265             Class representing a non-descript PyObject* value in the inferior
00266             process for when we don't have a custom scraper, intended to have
00267             a sane repr().
00268             """
00269 
00270             def __init__(self, tp_name, address):
00271                 self.tp_name = tp_name
00272                 self.address = address
00273 
00274             def __repr__(self):
00275                 # For the NULL pointer, we have no way of knowing a type, so
00276                 # special-case it as per
00277                 # http://bugs.python.org/issue8032#msg100882
00278                 if self.address == 0:
00279                     return '0x0'
00280                 return '<%s at remote 0x%x>' % (self.tp_name, self.address)
00281 
00282         return FakeRepr(self.safe_tp_name(),
00283                         long(self._gdbval))

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.pyop_field (   self,
  name 
) [inherited]
Get a PyObjectPtr for the given PyObject* field within this PyObject,
coping with some python 2 versus python 3 differences.

Definition at line 187 of file libpython.py.

00187 
00188     def pyop_field(self, name):
00189         '''
00190         Get a PyObjectPtr for the given PyObject* field within this PyObject,
00191         coping with some python 2 versus python 3 differences.
00192         '''
00193         return PyObjectPtr.from_pyobject_ptr(self.field(name))

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.safe_tp_name (   self) [inherited]

Definition at line 235 of file libpython.py.

00235 
00236     def safe_tp_name(self):
00237         try:
00238             return self.type().field('tp_name').string()
00239         except NullPyObjectPtr:
00240             # NULL tp_name?
00241             return 'unknown'
00242         except RuntimeError:
00243             # Can't even read the object at all?
00244             return 'unknown'

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.subclass_from_type (   cls,
  t 
) [inherited]
Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
(PyTypeObject*), determine the corresponding subclass of PyObjectPtr
to use

Ideally, we would look up the symbols for the global types, but that
isn't working yet:
  (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  NotImplementedError: Symbol type not yet supported in Python scripts.
  Error while executing Python code.

For now, we use tp_flags, after doing some string comparisons on the
tp_name for some special-cases that don't seem to be visible through
flags

Definition at line 295 of file libpython.py.

00295 
00296     def subclass_from_type(cls, t):
00297         '''
00298         Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
00299         (PyTypeObject*), determine the corresponding subclass of PyObjectPtr
00300         to use
00301 
00302         Ideally, we would look up the symbols for the global types, but that
00303         isn't working yet:
00304           (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
00305           Traceback (most recent call last):
00306             File "<string>", line 1, in <module>
00307           NotImplementedError: Symbol type not yet supported in Python scripts.
00308           Error while executing Python code.
00309 
00310         For now, we use tp_flags, after doing some string comparisons on the
00311         tp_name for some special-cases that don't seem to be visible through
00312         flags
00313         '''
00314         try:
00315             tp_name = t.field('tp_name').string()
00316             tp_flags = int(t.field('tp_flags'))
00317         except RuntimeError:
00318             # Handle any kind of error e.g. NULL ptrs by simply using the base
00319             # class
00320             return cls
00321 
00322         #print 'tp_flags = 0x%08x' % tp_flags
00323         #print 'tp_name = %r' % tp_name
00324 
00325         name_map = {'bool': PyBoolObjectPtr,
00326                     'classobj': PyClassObjectPtr,
00327                     'instance': PyInstanceObjectPtr,
00328                     'NoneType': PyNoneStructPtr,
00329                     'frame': PyFrameObjectPtr,
00330                     'set' : PySetObjectPtr,
00331                     'frozenset' : PySetObjectPtr,
00332                     'builtin_function_or_method' : PyCFunctionObjectPtr,
00333                     }
00334         if tp_name in name_map:
00335             return name_map[tp_name]
00336 
00337         if tp_flags & Py_TPFLAGS_HEAPTYPE:
00338             return HeapTypeObjectPtr
00339 
00340         if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
00341             return PyLongObjectPtr
00342         if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
00343             return PyListObjectPtr
00344         if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
00345             return PyTupleObjectPtr
00346         if tp_flags & Py_TPFLAGS_BYTES_SUBCLASS:
00347             return PyBytesObjectPtr
00348         if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
00349             return PyUnicodeObjectPtr
00350         if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
00351             return PyDictObjectPtr
00352         if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
00353             return PyBaseExceptionObjectPtr
00354         #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
00355         #    return PyTypeObjectPtr
00356 
00357         # Use the base class:
00358         return cls

def libpython.PyObjectPtr.type (   self) [inherited]

Definition at line 217 of file libpython.py.

00217 
00218     def type(self):
00219         return PyTypeObjectPtr(self.field('ob_type'))

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyObjectPtr.write_field_repr (   self,
  name,
  out,
  visited 
) [inherited]
Extract the PyObject* field named "name", and write its representation
to file-like object "out"

Definition at line 194 of file libpython.py.

00194 
00195     def write_field_repr(self, name, out, visited):
00196         '''
00197         Extract the PyObject* field named "name", and write its representation
00198         to file-like object "out"
00199         '''
00200         field_obj = self.pyop_field(name)
00201         field_obj.write_repr(out, visited)

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyFrameObjectPtr.write_repr (   self,
  out,
  visited 
)
Write a string representation of the value scraped from the inferior
process to "out", a file-like object.

Reimplemented from libpython.PyObjectPtr.

Definition at line 917 of file libpython.py.

00917 
00918     def write_repr(self, out, visited):
00919         if self.is_optimized_out():
00920             out.write('(frame information optimized out)')
00921             return
00922         out.write('Frame 0x%x, for file %s, line %i, in %s ('
00923                   % (self.as_address(),
00924                      self.co_filename.proxyval(visited),
00925                      self.current_line_num(),
00926                      self.co_name.proxyval(visited)))
00927         first = True
00928         for pyop_name, pyop_value in self.iter_locals():
00929             if not first:
00930                 out.write(', ')
00931             first = False
00932 
00933             out.write(pyop_name.proxyval(visited))
00934             out.write('=')
00935             pyop_value.write_repr(out, visited)
00936 
00937         out.write(')')

Here is the call graph for this function:


Member Data Documentation

Reimplemented from libpython.PyObjectPtr.

Definition at line 807 of file libpython.py.

Definition at line 271 of file libpython.py.

Definition at line 813 of file libpython.py.

Definition at line 815 of file libpython.py.

Definition at line 814 of file libpython.py.

Definition at line 819 of file libpython.py.

Definition at line 820 of file libpython.py.

Definition at line 818 of file libpython.py.

Definition at line 817 of file libpython.py.

Definition at line 107 of file object.h.

struct _typeobject* _object::ob_type [inherited]

Definition at line 108 of file object.h.

Definition at line 270 of file libpython.py.


The documentation for this class was generated from the following file: