コード例 #1
0
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    pyop = gdb.Value(addr).cast(_type_pyop)
    try:
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >=0 and ob_refcnt < 0xffff:
            obtype = pyop['ob_type']
            if obtype != 0:
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    if type_ob_size > 0xffff:
                        return 0

                    for fieldname in ('tp_del', 'tp_mro', 'tp_init', 'tp_getset'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except (RuntimeError, UnicodeDecodeError):
        pass # Not a python object (or corrupt)
コード例 #2
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    pyop = gdb.Value(addr).cast(_type_pyop)
    try:
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >=0 and ob_refcnt < 0xffff:
            obtype = pyop['ob_type']
            if obtype != 0:
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    if type_ob_size > 0xffff:
                        return 0

                    for fieldname in ('tp_del', 'tp_mro', 'tp_init', 'tp_getset'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except (RuntimeError, UnicodeDecodeError):
        pass # Not a python object (or corrupt)
コード例 #3
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
    def get_attr_dict(self):
        '''
        Get the PyDictObject ptr representing the attribute dictionary
        (or None if there's a problem)
        '''
        from heap import type_char_ptr
        try:
            typeobj = self.type()
            dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
            if dictoffset != 0:
                if dictoffset < 0:
                    type_PyVarObject_ptr = caching_lookup_type('PyVarObject').pointer()
                    tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
                    if tsize < 0:
                        tsize = -tsize
                    size = _PyObject_VAR_SIZE(typeobj, tsize)
                    dictoffset += size
                    assert dictoffset > 0
                    if dictoffset % SIZEOF_VOID_P != 0:
                        # Corrupt somehow?
                        return None

                dictptr = self._gdbval.cast(type_char_ptr) + dictoffset
                PyObjectPtrPtr = caching_lookup_type('PyObject').pointer().pointer()
                dictptr = dictptr.cast(PyObjectPtrPtr)
                return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
        except RuntimeError:
            # Corrupt data somewhere; fail safe
            pass

        # Not found, or some kind of error:
        return None
コード例 #4
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
def as_python_object(addr):
    '''Given an address of an allocation, determine if it holds a PyObject,
    or a PyGC_Head

    Return a WrappedPointer for the PyObject* if it does (which might have a
    different location c.f. when PyGC_Head was allocated)

    Return None if it doesn't look like a PyObject*'''
    # Try casting to PyObject* ?
    # FIXME: what about the debug allocator?
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_PyGC_Head = caching_lookup_type('PyGC_Head')
    except RuntimeError:
        # not linked against python
        return None
    pyop = is_pyobject_ptr(addr)
    if pyop:
        return pyop
    else:
        # maybe a GC type:
        _type_PyGC_Head_ptr = _type_PyGC_Head.pointer()
        gc_ptr = gdb.Value(addr).cast(_type_PyGC_Head_ptr)
        # print gc_ptr.dereference()

        PYGC_REFS_REACHABLE = -3

        if gc_ptr['gc']['gc_refs'] == PYGC_REFS_REACHABLE:  # FIXME: need to cover other values
            pyop = is_pyobject_ptr(gdb.Value(addr + _type_PyGC_Head.sizeof))
            if pyop:
                return pyop
コード例 #5
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
def as_python_object(addr):
    '''Given an address of an allocation, determine if it holds a PyObject,
    or a PyGC_Head

    Return a WrappedPointer for the PyObject* if it does (which might have a
    different location c.f. when PyGC_Head was allocated)

    Return None if it doesn't look like a PyObject*'''
    # Try casting to PyObject* ?
    # FIXME: what about the debug allocator?
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_PyGC_Head = caching_lookup_type('PyGC_Head')
    except RuntimeError:
        # not linked against python
        return None
    pyop = is_pyobject_ptr(addr)
    if pyop:
        return pyop
    else:
        # maybe a GC type:
        _type_PyGC_Head_ptr = _type_PyGC_Head.pointer()
        gc_ptr = gdb.Value(addr).cast(_type_PyGC_Head_ptr)
        # print gc_ptr.dereference()

        # PYGC_REFS_REACHABLE = -3

        if gc_ptr['gc']['gc_refs'] in (
                -2, -3, -4):  # FIXME: need to cover other values
            pyop = is_pyobject_ptr(gdb.Value(addr + _type_PyGC_Head.sizeof))
            if pyop:
                return pyop
コード例 #6
0
    def get_attr_dict(self):
        '''
        Get the PyDictObject ptr representing the attribute dictionary
        (or None if there's a problem)
        '''
        from heap import type_char_ptr
        try:
            typeobj = self.type()
            dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
            if dictoffset != 0:
                if dictoffset < 0:
                    type_PyVarObject_ptr = caching_lookup_type('PyVarObject').pointer()
                    tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
                    if tsize < 0:
                        tsize = -tsize
                    size = _PyObject_VAR_SIZE(typeobj, tsize)
                    dictoffset += size
                    assert dictoffset > 0
                    if dictoffset % SIZEOF_VOID_P != 0:
                        # Corrupt somehow?
                        return None

                dictptr = self._gdbval.cast(type_char_ptr) + dictoffset
                PyObjectPtrPtr = caching_lookup_type('PyObject').pointer().pointer()
                dictptr = dictptr.cast(PyObjectPtrPtr)
                return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
        except RuntimeError:
            # Corrupt data somewhere; fail safe
            pass

        # Not found, or some kind of error:
        return None
コード例 #7
0
ファイル: glibc.py プロジェクト: m0t/gdb-heap
 def __str__(self):
     corruptFlag = False
     result = ('<%s chunk=0x%x mem=0x%x'
               % (self.__class__.__name__,
                  self.as_address(),
                  self.as_mem()))
     if self.has_PREV_INUSE():
         result += ' PREV_INUSE'
     else:
         try:
             result += ' prev_size=%i' % self.field('prev_size')
         except gdb.MemoryError:
             corruptFlag = True
             result += ' prev_size=???'
     if self.has_NON_MAIN_ARENA():
         result += ' NON_MAIN_ARENA'
     if self.has_IS_MMAPPED():
         result += ' IS_MMAPPED'
     else:
         if self.is_inuse():
             result += ' inuse'
         else:
             result += ' free'
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     try:
         result += ' chunksize=%i memsize=%i>' % (self.chunksize(), self.memsize())
     except gdb.MemoryError:
         result += ' chunksize=??? memsize=???>'
         corruptFlag = True
     if corruptFlag:
         result += "<CORRUPT CHUNK>"
     return result
コード例 #8
0
ファイル: gobject.py プロジェクト: alexmgr/gdb-heap
def as_gtype_instance(addr, size):
    #type_GObject_ptr = caching_lookup_type('GObject').pointer()
    try:
        type_GTypeInstance_ptr = caching_lookup_type('GTypeInstance').pointer()
    except RuntimeError:
        # Not linked against GLib?
        return None

    gobj = gdb.Value(addr).cast(type_GTypeInstance_ptr)
    try:
        gtype = gobj['g_class']['g_type']
        #print 'gtype', gtype
        typenode = get_typenode_for_gtype(gtype)
        # If I remove the next line, we get errors like:
        #   Cannot access memory at address 0xd1a712caa5b6e5c0
        # Does this line give us an early chance to raise an exception?
        #print 'typenode', typenode
        # It appears to be in the coercion to boolean here:
        # if typenode:
        if typenode is not None:
            #print 'typenode.dereference()', typenode.dereference()
            return GTypeInstancePtr.from_gtypeinstance_ptr(addr, typenode)
    except RuntimeError:
        # Any random buffer that we point this at that isn't a GTypeInstance (or
        # GObject) is likely to raise a RuntimeError at some point in the above
        pass
    return None
コード例 #9
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
def _PyObject_VAR_SIZE(typeobj, nitems):
    type_size_t = caching_lookup_type('size_t')
    return ( ( typeobj.field('tp_basicsize') +
               nitems * typeobj.field('tp_itemsize') +
               (SIZEOF_VOID_P - 1)
             ) & ~(SIZEOF_VOID_P - 1)
           ).cast(type_size_t)
コード例 #10
0
def as_gtype_instance(addr, size):
    #type_GObject_ptr = caching_lookup_type('GObject').pointer()
    try:
        type_GTypeInstance_ptr = caching_lookup_type('GTypeInstance').pointer()
    except RuntimeError:
        # Not linked against GLib?
        return None

    gobj = gdb.Value(addr).cast(type_GTypeInstance_ptr)
    try:
        gtype = gobj['g_class']['g_type']
        #print 'gtype', gtype
        typenode = get_typenode_for_gtype(gtype)
        # If I remove the next line, we get errors like:
        #   Cannot access memory at address 0xd1a712caa5b6e5c0
        # Does this line give us an early chance to raise an exception?
        #print 'typenode', typenode
        # It appears to be in the coercion to boolean here:
        # if typenode:
        if typenode is not None:
            #print 'typenode.dereference()', typenode.dereference()
            return GTypeInstancePtr.from_gtypeinstance_ptr(addr, typenode)
    except RuntimeError:
        # Any random buffer that we point this at that isn't a GTypeInstance (or
        # GObject) is likely to raise a RuntimeError at some point in the above
        pass
    return None
コード例 #11
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
    def categorize_refs(self, usage_set, level=0, detail=None):
        cl_name = self.cl_name()
        # print 'cl_name', cl_name

        # Visit the in_dict:
        in_dict = self.field('in_dict')
        # print 'in_dict', in_dict

        dict_detail = '%s.__dict__' % cl_name

        # Mark the ptr as being a dictionary, adding detail
        usage_set.set_addr_category(obj_addr_to_gc_addr(in_dict),
                                    Category('cpython', 'PyDictObject', dict_detail),
                                    level=1)

        # Visit ma_table:
        _type_PyDictObject_ptr = caching_lookup_type('PyDictObject').pointer()
        in_dict = in_dict.cast(_type_PyDictObject_ptr)

        ma_table = long(in_dict['ma_table'])

        # Record details:
        usage_set.set_addr_category(ma_table,
                                    Category('cpython', 'PyDictEntry table', dict_detail),
                                    level=2)
        return True
コード例 #12
0
def _PyObject_VAR_SIZE(typeobj, nitems):
    type_size_t = caching_lookup_type('size_t')
    return ( ( typeobj.field('tp_basicsize') +
               nitems * typeobj.field('tp_itemsize') +
               (SIZEOF_VOID_P - 1)
             ) & ~(SIZEOF_VOID_P - 1)
           ).cast(type_size_t)
コード例 #13
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
    def categorize_refs(self, usage_set, level=0, detail=None):
        return True  # FIXME
        cl_name = self.cl_name()
        # print 'cl_name', cl_name

        # Visit the in_dict:
        in_dict = self.field('in_dict')
        # print 'in_dict', in_dict

        dict_detail = '%s.__dict__' % cl_name

        # Mark the ptr as being a dictionary, adding detail
        usage_set.set_addr_category(obj_addr_to_gc_addr(in_dict),
                                    Category('cpython', 'PyDictObject',
                                             dict_detail),
                                    level=1)

        # Visit ma_table:
        _type_PyDictObject_ptr = caching_lookup_type('PyDictObject').pointer()
        in_dict = in_dict.cast(_type_PyDictObject_ptr)

        ma_table = int(in_dict['ma_table'])

        # Record details:
        usage_set.set_addr_category(ma_table,
                                    Category('cpython', 'PyDictEntry table',
                                             dict_detail),
                                    level=2)
        return True
コード例 #14
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
    def from_pyobject_ptr(cls, addr):
        ob_type = addr['ob_type']
        tp_flags = ob_type['tp_flags']
        if tp_flags & Py_TPFLAGS_HEAPTYPE:
            return HeapTypeObjectPtr(addr)

        if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
            return PyUnicodeObjectPtr(addr.cast(caching_lookup_type('PyUnicodeObject').pointer()))

        if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
            return PyDictObjectPtr(addr.cast(caching_lookup_type('PyDictObject').pointer()))

        tp_name = ob_type['tp_name'].string()
        if tp_name == 'instance':
            __type_PyInstanceObjectPtr = caching_lookup_type('PyInstanceObject').pointer()
            return PyInstanceObjectPtr(addr.cast(__type_PyInstanceObjectPtr))

        return PyObjectPtr(addr)
コード例 #15
0
    def from_pyobject_ptr(cls, addr):
        ob_type = addr['ob_type']
        tp_flags = ob_type['tp_flags']
        if tp_flags & Py_TPFLAGS_HEAPTYPE:
            return HeapTypeObjectPtr(addr)

        if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
            return PyUnicodeObjectPtr(addr.cast(caching_lookup_type('PyUnicodeObject').pointer()))

        if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
            return PyDictObjectPtr(addr.cast(caching_lookup_type('PyDictObject').pointer()))

        tp_name = ob_type['tp_name'].string()
        if tp_name == 'instance':
            __type_PyInstanceObjectPtr = caching_lookup_type('PyInstanceObject').pointer()
            return PyInstanceObjectPtr(addr.cast(__type_PyInstanceObjectPtr))

        return PyObjectPtr(addr)
コード例 #16
0
ファイル: sqlite.py プロジェクト: fwugist/gdb-heap
def categorize_sqlite3(addr, usage_set, visited):
    # "struct sqlite3" is defined in src/sqliteInt.h, which is an internal header
    ptr_type = caching_lookup_type('sqlite3').pointer()    
    obj_ptr = gdb.Value(addr).cast(ptr_type)
    # print obj_ptr.dereference()

    aDb = obj_ptr['aDb']
    Db_addr = long(aDb)
    Db_malloc_addr = Db_addr - 8
    if usage_set.set_addr_category(Db_malloc_addr, Category('sqlite3', 'struct Db', None), visited):
        print aDb['pBt'].dereference()
コード例 #17
0
ファイル: sqlite.py プロジェクト: PMickael/gdb-heap
def categorize_sqlite3(addr, usage_set, visited):
    # "struct sqlite3" is defined in src/sqliteInt.h, which is an internal header
    ptr_type = caching_lookup_type('sqlite3').pointer()
    obj_ptr = gdb.Value(addr).cast(ptr_type)
    # print obj_ptr.dereference()

    aDb = obj_ptr['aDb']
    Db_addr = int(aDb)
    Db_malloc_addr = Db_addr - 8
    if usage_set.set_addr_category(Db_malloc_addr, Category('sqlite3', 'struct Db', None), visited):
        print(aDb['pBt'].dereference())
コード例 #18
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
 def iter_free_blocks(self):
     '''Yield the sequence of free blocks within this pool.  Doesn't include
     the areas after nextoffset that have never been allocated'''
     # print self._gdbval.dereference()
     size = self.block_size()
     freeblock = self.field('freeblock')
     _type_block_ptr_ptr = caching_lookup_type('unsigned char').pointer().pointer()
     # Walk the singly-linked list of free blocks for this chunk
     while long(freeblock) != 0:
         # print 'freeblock:', (fmt_addr(long(freeblock)), long(size))
         yield (long(freeblock), long(size))
         freeblock = freeblock.cast(_type_block_ptr_ptr).dereference()
コード例 #19
0
 def iter_free_blocks(self):
     '''Yield the sequence of free blocks within this pool.  Doesn't include
     the areas after nextoffset that have never been allocated'''
     # print self._gdbval.dereference()
     size = self.block_size()
     freeblock = self.field('freeblock')
     _type_block_ptr_ptr = caching_lookup_type('unsigned char').pointer().pointer()
     # Walk the singly-linked list of free blocks for this chunk
     while to_int(freeblock) != 0:
         # print 'freeblock:', (fmt_addr(int(freeblock)), int(size))
         yield (to_int(freeblock), to_int(size))
         freeblock = freeblock.cast(_type_block_ptr_ptr).dereference()
コード例 #20
0
ファイル: gobject.py プロジェクト: fwugist/gdb-heap
 def __init__(self, addr, typenode, typename):
     # Try to cast the ptr to the named type:
     addr = gdb.Value(addr)
     try:
         if is_typename_castable(typename):
             # This requires, say, gtk2-debuginfo:
             ptr_type = caching_lookup_type(typename).pointer()
             addr = addr.cast(ptr_type)
             #print typename, addr.dereference()
             #if typename == 'GdkPixbuf':
             #    print 'GOT PIXELS', addr['pixels']
     except RuntimeError, e:
         pass
コード例 #21
0
ファイル: gobject.py プロジェクト: doctau/gdb-heap
 def __init__(self, addr, typenode, typename):
     # Try to cast the ptr to the named type:
     addr = gdb.Value(addr)
     try:
         if is_typename_castable(typename):
             # This requires, say, gtk2-debuginfo:
             ptr_type = caching_lookup_type(typename).pointer()
             addr = addr.cast(ptr_type)
             #print typename, addr.dereference()
             #if typename == 'GdkPixbuf':
             #    print 'GOT PIXELS', addr['pixels']
     except RuntimeError, e:
         pass
コード例 #22
0
ファイル: gobject.py プロジェクト: alexmgr/gdb-heap
    def categorize_refs(self, usage_set, level=0, detail=None):
        priv_type = caching_lookup_type('GdkImagePrivateX11').pointer()
        priv_data = WrappedPointer(self._gdbval['windowing_data'].cast(priv_type))

        usage_set.set_addr_category(priv_data.as_address(),
                                    Category('GType', 'GdkImagePrivateX11', ''),
                                    level=level+1, debug=True)

        ximage = WrappedPointer(priv_data.field('ximage'))
        dims = '%sw x %sh x %sbpp' % (ximage.field('width'),
                                      ximage.field('height'),
                                      ximage.field('depth'))
        usage_set.set_addr_category(ximage.as_address(),
                                    Category('X11', 'Image', dims),
                                    level=level+2, debug=True)

        usage_set.set_addr_category(int(ximage.field('data')),
                                    Category('X11', 'Image data', dims),
                                    level=level+2, debug=True)
コード例 #23
0
 def __str__(self):
     result = ('<%s chunk=0x%x mem=0x%x' %
               (self.__class__.__name__, self.as_address(), self.as_mem()))
     if self.has_PREV_INUSE():
         result += ' PREV_INUSE'
     else:
         result += ' prev_size=%i' % self.field('prev_size')
     if self.has_NON_MAIN_ARENA():
         result += ' NON_MAIN_ARENA'
     if self.has_IS_MMAPPED():
         result += ' IS_MMAPPED'
     else:
         if self.is_inuse():
             result += ' inuse'
         else:
             result += ' free'
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     result += ' chunksize=%i memsize=%i>' % (self.chunksize(),
                                              self.chunksize() -
                                              (2 * SIZE_SZ))
     return result
コード例 #24
0
ファイル: glibc.py プロジェクト: alexmgr/gdb-heap
 def __str__(self):
     result = ('<%s chunk=0x%x mem=0x%x'
               % (self.__class__.__name__,
                  self.as_address(),
                  self.as_mem()))
     if self.has_PREV_INUSE():
         result += ' PREV_INUSE'
     else:
         result += ' prev_size=%i' % self.field('prev_size')
     if self.has_NON_MAIN_ARENA():
         result += ' NON_MAIN_ARENA'
     if self.has_IS_MMAPPED():
         result += ' IS_MMAPPED'
     else:
         if self.is_inuse():
             result += ' inuse'
         else:
             result += ' free'
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     result += ' chunksize=%i memsize=%i>' % (self.chunksize(),
                                              self.chunksize() - (2 * SIZE_SZ))
     return result
コード例 #25
0
    def categorize_refs(self, usage_set, level=0, detail=None):
        priv_type = caching_lookup_type('GdkImagePrivateX11').pointer()
        priv_data = WrappedPointer(
            self._gdbval['windowing_data'].cast(priv_type))

        usage_set.set_addr_category(priv_data.as_address(),
                                    Category('GType', 'GdkImagePrivateX11',
                                             ''),
                                    level=level + 1,
                                    debug=True)

        ximage = WrappedPointer(priv_data.field('ximage'))
        dims = '%sw x %sh x %sbpp' % (ximage.field('width'),
                                      ximage.field('height'),
                                      ximage.field('depth'))
        usage_set.set_addr_category(ximage.as_address(),
                                    Category('X11', 'Image', dims),
                                    level=level + 2,
                                    debug=True)

        usage_set.set_addr_category(int(ximage.field('data')),
                                    Category('X11', 'Image data', dims),
                                    level=level + 2,
                                    debug=True)
コード例 #26
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
def obj_addr_to_gc_addr(addr):
    '''Given a PyObject* address, convert to a PyGC_Head* address
    (i.e. the allocator's view of the same)'''
    #print 'obj_addr_to_gc_addr(%s)' % fmt_addr(long(addr))
    _type_PyGC_Head = caching_lookup_type('PyGC_Head')
    return long(addr) - _type_PyGC_Head.sizeof
コード例 #27
0
ファイル: glibc.py プロジェクト: alexmgr/gdb-heap
 def gdb_type(cls):
     # Deferred lookup of the "mchunkptr" type:
     return caching_lookup_type('mchunkptr')
コード例 #28
0
ファイル: glibc.py プロジェクト: alexmgr/gdb-heap
 def as_mem(self):
     # Analog of chunk2mem: the address as seen by the program (e.g. malloc)
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     return self.as_address() + (2 * SIZE_SZ)
コード例 #29
0
ファイル: glibc.py プロジェクト: m0t/gdb-heap
 def memsize(self):
     '''Returns size of the allocated block'''
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     return self.chunksize() - (2 * SIZE_SZ)
コード例 #30
0
 def gdb_type(cls):
     # Deferred lookup of the "mchunkptr" type:
     return caching_lookup_type('mchunkptr')
コード例 #31
0
 def as_mem(self):
     # Analog of chunk2mem: the address as seen by the program (e.g. malloc)
     SIZE_SZ = caching_lookup_type('size_t').sizeof
     return self.as_address() + (2 * SIZE_SZ)
コード例 #32
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
def POOL_OVERHEAD():
    return ROUNDUP(caching_lookup_type('struct pool_header').sizeof)
コード例 #33
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# C++ support
import re

import gdb

from heap import caching_lookup_type, looks_like_ptr
from heap.compat import execute

void_ptr_ptr = caching_lookup_type('void').pointer().pointer()


def get_class_name(addr, size):
    # Try to detect a vtable ptr at the top of this object:
    vtable = gdb.Value(addr).cast(void_ptr_ptr).dereference()
    if not looks_like_ptr(vtable):
        return None

    info = execute('info sym (void *)0x%x' % long(vtable))
    # "vtable for Foo + 8 in section .rodata of /home/david/heap/test_cplusplus"
    m = re.match('vtable for (.*) \+ (.*)', info)
    if m:
        return m.group(1)
    # Not matched:
    return None
コード例 #34
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
def obj_addr_to_gc_addr(addr):
    '''Given a PyObject* address, convert to a PyGC_Head* address
    (i.e. the allocator's view of the same)'''
    #print 'obj_addr_to_gc_addr(%s)' % fmt_addr(int(addr))
    _type_PyGC_Head = caching_lookup_type('PyGC_Head')
    return int(addr) - _type_PyGC_Head.sizeof
コード例 #35
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    try:
        typeop = pyop = gdb.Value(addr).cast(_type_pyop)

        # If we follow type chain on a PyObject long enough, we should arrive
        # at 'type' and type(type) should be 'type'.
        # The levels are:     a <- b means a = type(b)
        # 0 - type
        # 1 - type <- class A
        #     type <- class M(type)
        # 2 - type <- class A <- A()
        #     type <- class M(type) <- class B(metaclass=M)
        # 3 - type <- class M(type) <- class B(metaclass=M) <- B()
        for i in range(4):
            if typeop['ob_type'] == typeop:
                return PyObjectPtr.from_pyobject_ptr(pyop)
            typeop = typeop['ob_type'].cast(_type_pyop)

        return 0

        # gdb.write('PYOP {}\n'.format(pyop))
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >= 0 and ob_refcnt < 0xffff:
            # gdb.write('refcnt ok {}\n'.format(int(ob_refcnt)))
            obtype = pyop['ob_type']
            if looks_like_ptr(obtype):
                # gdb.write('obtype ok {}\n'.format(obtype))
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    # gdb.write('type refcnt ok\n')
                    # type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    # if type_ob_size > 0xffff:
                    #     return 0

                    # gdb.write('ob size ok\n')

                    for fieldname in ('tp_base', 'tp_free', 'tp_repr',
                                      'tp_new'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # gdb.write('methods ok\n')

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except UnicodeDecodeError as e:
        # print('is_pyobject_ptr 0x{:x}'.format(addr))
        # gdb.write(str(e) + '\n')
        pass

    except RuntimeError:
        pass  # Not a python object (or corrupt)
コード例 #36
0
ファイル: commands.py プロジェクト: m0t/gdb-heap
    def invoke(self, args, from_tty):
        from heap.glibc import iter_mappings,lookup_symbol
        from heap import WrappedPointer,caching_lookup_type
        SIZE_SZ = caching_lookup_type('size_t').sizeof
        type_size_t = gdb.lookup_type('size_t')
        type_size_t_ptr = type_size_t.pointer()

        arg_list = gdb.string_to_argv(args)
        parser = argparse.ArgumentParser(add_help=True, usage="objdump  [-v][-s SIZE] <ADDR>")
        parser.add_argument('addr', metavar='ADDR', type=str, nargs=1, help="Target address")
        parser.add_argument('-s', dest='size', default=None, help='Total dump size')
        parser.add_argument('-v', dest='verbose', action="store_true", default=False, help='Verbose')
        
        try:
            args_dict = parser.parse_args(args=arg_list)
        except:
            return

        addr_arg = args_dict.addr[0]
        if addr_arg.startswith('0x'):
            addr = int(addr_arg, 16)
        else:
            addr = int(addr_arg)

        if args_dict.size:
            if args_dict.size.startswith('0x'):
                total_size = int(args_dict.size, 16)
            else:
                total_size = int(args_dict.size)
        else:
            total_size = 10 * SIZE_SZ

        if args_dict.verbose:
            print('Searching in the following object ranges')
            print('-------------------------------------------------')
        text = [] #list of tuples (start, end, pathname, ...) of a valid memory map
        #XXX why pid would be 0?
        for pid in [ o.pid for o in gdb.inferiors() if o.pid !=0 ]:
            for r in iter_mappings(pid):
                if args_dict.verbose: print("%s - %s : %s" % (hex(r[0]), hex(r[1]), r[2]))
                text.append((r[0], r[1], r[2]))

        print('\nDumping Object at address %s' % fmt_addr(addr))
        print('-------------------------------------------------')
        
        for a in range(addr, addr + (total_size * SIZE_SZ), SIZE_SZ):
            ptr = WrappedPointer(gdb.Value(a).cast(type_size_t_ptr))
            #dereference first, at the first access denied bail out, dont go further
            try:
                val = ptr.dereference()
                found = False
                val_int = int(str(val.cast(type_size_t))) #XXX Error occurred in Python command: invalid literal for int() with base 10: '0x418'
                pathname = ""
                for t in text:
                    if val_int >= t[0] and val_int < t[1]:
                        found = True
                        pathname = t[2]
                
                if found:
                    sym = lookup_symbol(val_int)
                    if sym:
                        out_line = "%s => %s (%s in %s)" % (fmt_addr(ptr.as_address()), fmt_addr(val_int), sym, pathname )
                    else:
                        out_line = "%s => %s (%s)" % (fmt_addr(ptr.as_address()), fmt_addr(val_int), pathname )
                else:
                    out_line = "%s => %s" % (fmt_addr(ptr.as_address()), fmt_addr(val_int) )

                #if it's not a symbol, try a string
                # try just a few chars
                #if not found:

                print(out_line)
            except gdb.MemoryError:
                print("Error accessing memory at %s" % fmt_addr(ptr.as_address()))
                return
コード例 #37
0
ファイル: cpython.py プロジェクト: iafilatov/gdb-heap
 def gdb_type(cls):
     # Deferred lookup of the "poolp" type:
     return caching_lookup_type('poolp')
コード例 #38
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
 def gdb_type(cls):
     # Deferred lookup of the "poolp" type:
     return caching_lookup_type('poolp')
コード例 #39
0
ファイル: cplusplus.py プロジェクト: doctau/gdb-heap
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# C++ support
import re

import gdb

from heap import caching_lookup_type, looks_like_ptr
from heap.compat import execute

void_ptr_ptr = caching_lookup_type('void').pointer().pointer()

def get_class_name(addr, size):
    # Try to detect a vtable ptr at the top of this object:
    vtable = gdb.Value(addr).cast(void_ptr_ptr).dereference()
    if not looks_like_ptr(vtable):
        return None

    info = execute('info sym (void *)0x%x' % long(vtable))
    # "vtable for Foo + 8 in section .rodata of /home/david/heap/test_cplusplus"
    m = re.match('vtable for (.*) \+ (.*)', info)
    if m:
        return m.group(1)
    # Not matched:
    return None
    
コード例 #40
0
ファイル: cpython.py プロジェクト: doctau/gdb-heap
def POOL_OVERHEAD():
    return ROUNDUP(caching_lookup_type('struct pool_header').sizeof)
コード例 #41
0
ファイル: cplusplus.py プロジェクト: alexmgr/gdb-heap
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# C++ support
import re

import gdb

from heap import caching_lookup_type, looks_like_ptr
from heap.compat import execute

void_ptr_ptr = caching_lookup_type("void").pointer().pointer()


def get_class_name(addr, size):
    # Try to detect a vtable ptr at the top of this object:
    vtable = gdb.Value(addr).cast(void_ptr_ptr).dereference()
    if not looks_like_ptr(vtable):
        return None

    info = execute("info sym (void *)0x%x" % int(vtable))
    # "vtable for Foo + 8 in section .rodata of /home/david/heap/test_cplusplus"
    m = re.match("vtable for (.*) \+ (.*)", info)
    if m:
        return m.group(1)
    # Not matched:
    return None