123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- # GDB Sol extensions
-
- import gdb.printing
- import sys
- import traceback
-
- class _CatchExceptions(object):
- def __init__(self):
- self.excs = []
- def print_eidx(self, idx):
- traceback.print_exception(*self.excs[idx])
- def __enter__(self):
- pass
- def __exit__(self, t, v, tb):
- if t is not None:
- self.excs.append((t, v, tb))
- guard = _CatchExceptions()
-
- class DslArray(gdb.Function):
- '''Returns the (DSL_DATATYPE[]) array base of a dsl_array or dsl_seq (if it wraps an array), else NULL'''
-
- def __init__(self):
- super(DslArray, self).__init__('dsl_array')
-
- def invoke(self, val):
- with guard:
- stype = str(val.type)
- tp = gdb.lookup_type('sol_object_t').pointer()
- if str(val.type).startswith('dsl_seq'):
- if str(val['type']) != 'DSL_SEQ_ARRAY':
- return gdb.Value(0).cast(tp.pointer())
- val = val['array']
- if str(val.type).startswith('dsl_array'):
- return val['data'].dereference().cast(tp.array(val['len']))
- return gdb.Value(0).cast(tp.pointer())
- DslArray.instance = DslArray()
-
- class DslLen(gdb.Function):
- '''Returns the length of a DSL sequence'''
-
- def __init__(self):
- super(DslLen, self).__init__('dsl_array')
-
- def invoke(self, val):
- with guard:
- stype = str(val.type)
- if stype.startswith('dsl_seq'):
- return int(gdb.lookup_symbol('dsl_seq_len')[0].value()(val))
- if stype.startswith('dsl_array'):
- return int(gdb.lookup_symbol('dsl_array_len')[0].value()(val))
- if stype.startswith('dsl_list'):
- return int(gdb.lookup_symbol('dsl_list_len')[0].value()(val))
- return -1
- DslLen.instance = DslLen()
-
- class SolObj(gdb.Function):
- '''Casts the argument to a sol_object_t *'''
-
- def __init__(self):
- super(SolObj, self).__init__('sol_obj')
-
- def invoke(self, val):
- with guard:
- return val.cast(gdb.lookup_type('sol_object_t').pointer())
- SolObj.instance = SolObj()
-
- class SolObjectPrettyPrinter(object):
- STYPE_TO_DISPHINT = {
- 'SOL_SINGLET': 'string',
- 'SOL_INTEGER': 'number',
- 'SOL_FLOAT': 'number',
- 'SOL_STRING': 'string',
- 'SOL_LIST': 'array',
- 'SOL_MAP': 'map',
- 'SOL_MCELL': 'map',
- 'SOL_FUNCTION': 'function',
- 'SOL_CFUNCTION': 'function',
- 'SOL_STMT': 'syntax',
- 'SOL_EXPR': 'syntax',
- }
-
- def __init__(self, obj):
- self.obj = obj
-
- def display_hint(self):
- return self.STYPE_TO_DISPHINT.get(str(self.obj['type']), 'string')
-
- def to_string(self):
- with guard:
- return getattr(self, 'str_'+str(self.obj['type']), self.str_default)(self.obj)
-
- def str_default(self, obj):
- return '<Unknown object %r type %s>'%(obj, str(obj['type']))
-
- def str_SOL_SINGLET(self, obj):
- return obj['str']
-
- def str_SOL_INTEGER(self, obj):
- return str(obj['ival'])
-
- def str_SOL_FLOAT(self, obj):
- return str(obj['fval'])
-
- def str_SOL_STRING(self, obj):
- return obj['str']
-
- def str_SOL_LIST(self, obj):
- return '[List len=%d]'%(DslLen.instance.invoke(obj['seq']),)
-
- def str_SOL_MAP(self, obj):
- return '{Map len=%d}'%(DslLen.instance.invoke(obj['seq']),)
-
- def str_SOL_MCELL(self, obj):
- return '<{[%s] = %s}>'%(SolObjectPrettyPrinter(obj['key']).to_string(), SolObjectPrettyPrinter(obj['val']).to_string())
-
- def str_SOL_FUNCTION(self, obj):
- return '<Function %s>'%(obj['fname'],)
-
- def str_SOL_CFUNCTION(self, obj):
- return '<CFunction %r>'%(obj['cfunc'],)
-
- def str_SOL_STMT(self, obj):
- return str(obj['node'].cast(gdb.lookup_type('stmt_node').pointer())['type'])
-
- def str_SOL_EXPR(self, obj):
- return str(obj['node'].cast(gdb.lookup_type('expr_node').pointer())['type'])
-
- def children(self):
- with guard:
- stype = str(self.obj['type'])
- if stype in ('SOL_LIST', 'SOL_MAP'):
- if str(self.obj['seq']['type']) == 'DSL_SEQ_ARRAY':
- tp = gdb.lookup_type('sol_object_t').pointer()
- lseq = DslLen.instance.invoke(self.obj['seq'])
- arr = self.obj['seq']['array']['data'].dereference().cast(tp.array(lseq))
- if stype == 'SOL_LIST':
- return [(str(i), arr[i]) for i in range(lseq)]
- else:
- return sum([[(str(i)+'k', arr[i]['key']), (str(i)+'v', arr[i]['val'])] for i in range(lseq)], [])
- if stype == 'SOL_FUNCTION':
- return [('stmt', self.obj['func'].cast(gdb.lookup_type('stmt_node').pointer))]
- return []
-
- @classmethod
- def check_printable(cls, obj):
- with guard:
- stype = str(obj.type)
- if stype.startswith('sol_object_t') or stype.startswith('struct sol_tag_object_t'):
- return cls(obj)
- return None
-
- # pp = gdb.printing.RegexpCollectionPrettyPrinter('Sol')
- # pp.add_printer('sol_object_t', '^sol_object_t.*$', SolObjectPrettyPrinter)
- # pp.add_printer('sol_tag_object_t', '^struct sol_tag_object_t.*$', SolObjectPrettyPrinter)
- # gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
- gdb.pretty_printers.append(SolObjectPrettyPrinter.check_printable)
-
- print('Sol extensions loaded!')
|