Minor fixes in GDB scripts.
import gdb
import stx.support
class __instance ( object ):
"""
Generic object representation. Instance of this class
also implements gdb pretty-printing API and could therefore
used as a pretty printer
"""
def __init__(self, val):
#stx.support.Decorator.__init__(self, val)
#object.__setattr__(self, "_klass", None)
self._obj = val
self._klass = None
def display_hint(self):
'''
Pretty printer API
'''
return None
def to_string(self):
'''
Pretty printer API: Returns a human-readable represenation of the object.
'''
return self.display_string()
def __repr__(self):
return self.display_string()
def display_string(self):
try:
value = self.display_value()
klassName = '???'
klass = self.klass
if klass == None:
klassName = '?None?'
else:
klassName = klass.name
if (value == None):
return "0x%08x (%s)" % ( self.address , klassName )
else:
return "0x%08x (%s %s)" % ( self.address , klassName , value )
except:
survStartPtr = long(gdb.parse_and_eval("__survStartPtr"))
survEndPtr = long(gdb.parse_and_eval("__survEndPtr"))
if (survStartPtr <= self.address and self.address <= survEndPtr):
return "0x%08x (** survivor **)" % self.address
return "0x%08x (** err **)" % self.address
def display_value(self):
'''
Return a human-readable represenation of object's value, if sensible.
FOr instance, for integer or string it may be its respective value
'''
return None
@property
def address(self):
'''Return the address of the object in memory'''
return long(self._obj);
@property
def klass(self):
'''Return this object's class as an __instance value'''
if (self._klass == None):
self._klass = create(self._obj['o_class'])
return self._klass
@property
def size(self):
'''Return size of the objects in slots (excluding header)'''
# Not really 64bit safe...
return (self.size_b() - 12) / 4
def size_b(self):
'''Return size of the object in bytes, including header'''
return self._obj['o_size']
@property
def flags(self):
return self._obj['o_flags']
# Some flags defined in stc.h.
# !!! MAKE SURE they are in sync !!!
BYTEARRAY = 1
WORDARRAY = 2
LONGARRAY = 3
POINTERARRAY = 4
WKPOINTERARRAY = 5
FLOATARRAY = 6
DOUBLEARRAY = 7
SWORDARRAY = 8
SLONGARRAY = 9
LONGLONGARRAY = 10
SLONGLONGARRAY = 11
#
# reserved: 13-15
#
ARRAYMASK = 0x0F
BEHAVIOR_INSTS = 0x0010
FLOAT_INSTS = 0x0020
BLOCK_INSTS = 0x0040
METHOD_INSTS = 0x0080
CONTEXT_INSTS = 0x0100
BCONTEXT_INSTS = 0x0200
SYMBOL_INSTS = 0x0400
NONOBJECT_INSTS = 0x0800
EXTERNALBYTES_INSTS = 0x1000
EXTFUNC_INSTS = 0x010000
def create(val):
import stx.gdb.objects.stx_libbasic
addr = long(val)
# Here we should care for free/non objects
# by comparing address agains newspace
# boundaries.
# Well, later :-)
if (addr == 0):
return stx.gdb.objects.stx_libbasic.nil
if ((addr & 1) == 1):
return stx.gdb.objects.stx_libbasic.SmallInteger(val)
flags = long(val['o_class']['i_instvars'][1])
if ((flags & 1) == 1):
flags = flags >> 1
else:
raise Exception("Memory corruption? Class flags are not SmallInteger.")
if ((flags & BEHAVIOR_INSTS) != 0):
# Care for anonymous classes
size = (val['o_size'] - 12) / 4 # Not 64bit safe
if (size == 5):
return stx.gdb.objects.stx_libbasic.Behavior(val)
if (size == 6):
return stx.gdb.objects.stx_libbasic.ClassDescription(val)
if (size >= 17):
return stx.gdb.objects.stx_libbasic.Class(val)
if (size >= 7):
return stx.gdb.objects.stx_libbasic.Metaclass(val)
raise Exception("Funny behaviour-like size (%s)" % size)
if ((flags & SYMBOL_INSTS) != 0):
return stx.gdb.objects.stx_libbasic.Symbol(val)
return __instance(val)