Back to index

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

List of all members.

Public Member Functions

def iteritems
def proxyval
def write_repr
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 subclass_from_type
def from_pyobject_ptr
def get_gdb_type
def as_address

Public Attributes

 tp_name
 address
_PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt
struct _typeobjectob_type

Static Private Attributes

string _typename = 'PyDictObject'

Detailed Description

Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
within the process being debugged.

Definition at line 618 of file libpython.py.


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:

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:

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.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:

Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
analagous to dict.iteritems()

Definition at line 625 of file libpython.py.

00625 
00626     def iteritems(self):
00627         '''
00628         Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
00629         analagous to dict.iteritems()
00630         '''
00631         for i in safe_range(self.field('ma_mask') + 1):
00632             ep = self.field('ma_table') + i
00633             pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
00634             if not pyop_value.is_null():
00635                 pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
00636                 yield (pyop_key, pyop_value)

Here is the call graph for this function:

Here is the caller graph for this function:

def libpython.PyDictObjectPtr.proxyval (   self,
  visited 
)
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 from libpython.PyObjectPtr.

Definition at line 637 of file libpython.py.

00637 
00638     def proxyval(self, visited):
00639         # Guard against infinite loops:
00640         if self.as_address() in visited:
00641             return ProxyAlreadyVisited('{...}')
00642         visited.add(self.as_address())
00643 
00644         result = {}
00645         for pyop_key, pyop_value in self.iteritems():
00646             proxy_key = pyop_key.proxyval(visited)
00647             proxy_value = pyop_value.proxyval(visited)
00648             result[proxy_key] = proxy_value
00649         return result

Here is the call 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.PyDictObjectPtr.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 650 of file libpython.py.

00650 
00651     def write_repr(self, out, visited):
00652         # Guard against infinite loops:
00653         if self.as_address() in visited:
00654             out.write('{...}')
00655             return
00656         visited.add(self.as_address())
00657 
00658         out.write('{')
00659         first = True
00660         for pyop_key, pyop_value in self.iteritems():
00661             if not first:
00662                 out.write(', ')
00663             first = False
00664             pyop_key.write_repr(out, visited)
00665             out.write(': ')
00666             pyop_value.write_repr(out, visited)
00667         out.write('}')

Here is the call graph for this function:


Member Data Documentation

string libpython.PyDictObjectPtr._typename = 'PyDictObject' [static, private]

Reimplemented from libpython.PyObjectPtr.

Definition at line 623 of file libpython.py.

Definition at line 271 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: