qt - Python code in GDB init file .gdbinit -
i'm trying create ~/.gdbinit
contains qt pretty printers various qt objects, qstrings. want without qt creator, using regular gdb. i've placed file (this script modified form of scipts @ niko's blog):
# -*- coding: iso-8859-1 -*- # pretty-printers qt4. # copyright (c) 2009 niko sams <niko.sams@gmail.com> # program free software; can redistribute and/or modify # under terms of gnu general public license published # free software foundation; either version 2 of license, or # (at option) later version. # # program distributed in hope useful, # without warranty; without implied warranty of # merchantability or fitness particular purpose. see # gnu general public license more details. # # should have received copy of gnu general public license # along program. if not, see <http://www.gnu.org/licenses/>. import gdb import itertools import re import sys class qstringprinter: def __init__(self, val): self.val = val def to_string(self): #ret = "" #i = 0 size = self.val['d']['size'] #while < size: # char = self.val['d']['data'][i] # if (char > 127): # ret += "\\u%x" % int(char) # else: # ret += chr(char) # = + 1 #return ret dataascharpointer = self.val['d']['data'].cast(gdb.lookup_type("char").pointer()) return dataascharpointer.string(encoding = 'utf-16', length = size * 2) def display_hint (self): return 'string' class qbytearrayprinter: def __init__(self, val): self.val = val class _iterator: def __init__(self, data, size): self.data = data self.size = size self.count = 0 def __iter__(self): return self def next(self): if self.count >= self.size: raise stopiteration count = self.count self.count = self.count + 1 return ('[%d]' % count, self.data[count]) def children(self): return self._iterator(self.val['d']['data'], self.val['d']['size']) def to_string(self): #todo: handle charset correctly return self.val['d']['data'].string() def display_hint (self): return 'string' class qlistprinter: "print qlist" class _iterator: def __init__(self, nodetype, d): self.nodetype = nodetype self.d = d self.count = 0 def __iter__(self): return self def next(self): if self.count >= self.d['end'] - self.d['begin']: raise stopiteration count = self.count array = self.d['array'][self.d['begin'] + count] #from qtypeinfo::islarge islarge = self.nodetype.sizeof > gdb.lookup_type('void').pointer().sizeof #isstatic not needed anymore since qt 4.6 #ispointer = self.nodetype.code == gdb.type_code_ptr # ##unfortunately can't use qtypeinfo<t>::isstatic it's inlined, use ##this list of types use q_declare_typeinfo(t, q_movable_type) ##(obviously won't work custom types) #movabletypes = ['qrect', 'qrectf', 'qstring', 'qmargins', 'qlocale', 'qchar', 'qdate', 'qtime', 'qdatetime', 'qvector', # 'qregexpr', 'qpoint', 'qpointf', 'qbytearray', 'qsize', 'qsizef', 'qbitarray', 'qline', 'qlinef', 'qmodelindex', 'qpersitentmodelindex', # 'qvariant', 'qfileinfo', 'qurl', 'qxmlstreamattribute', 'qxmlstreamnamespacedeclaration', 'qxmlstreamnotationdeclaration', # 'qxmlstreamentitydeclaration'] #if movabletypes.count(self.nodetype.tag): # isstatic = false #else: # isstatic = not ispointer isstatic = false if islarge or isstatic: #see qlist::node::t() node = array.cast(gdb.lookup_type('qlist<%s>::node' % self.nodetype).pointer()) else: node = array.cast(gdb.lookup_type('qlist<%s>::node' % self.nodetype)) self.count = self.count + 1 return ('[%d]' % count, node['v'].cast(self.nodetype)) def __init__(self, val, container, itype): self.val = val self.container = container if itype == none: self.itype = self.val.type.template_argument(0) else: self.itype = gdb.lookup_type(itype) def children(self): return self._iterator(self.itype, self.val['d']) def to_string(self): if self.val['d']['end'] == self.val['d']['begin']: empty = "empty " else: empty = "" return "%s%s<%s>" % ( empty, self.container, self.itype ) class qvectorprinter: "print qvector" class _iterator: def __init__(self, nodetype, d, p): self.nodetype = nodetype self.d = d self.p = p self.count = 0 def __iter__(self): return self def next(self): if self.count >= self.p['size']: raise stopiteration count = self.count self.count = self.count + 1 return ('[%d]' % count, self.p['array'][count]) def __init__(self, val, container): self.val = val self.container = container self.itype = self.val.type.template_argument(0) def children(self): return self._iterator(self.itype, self.val['d'], self.val['p']) def to_string(self): if self.val['d']['size'] == 0: empty = "empty " else: empty = "" return "%s%s<%s>" % ( empty, self.container, self.itype ) class qlinkedlistprinter: "print qlinkedlist" class _iterator: def __init__(self, nodetype, begin, size): self.nodetype = nodetype self.it = begin self.pos = 0 self.size = size def __iter__(self): return self def next(self): if self.pos >= self.size: raise stopiteration pos = self.pos val = self.it['t'] self.it = self.it['n'] self.pos = self.pos + 1 return ('[%d]' % pos, val) def __init__(self, val): self.val = val self.itype = self.val.type.template_argument(0) def children(self): return self._iterator(self.itype, self.val['e']['n'], self.val['d']['size']) def to_string(self): if self.val['d']['size'] == 0: empty = "empty " else: empty = "" return "%sqlinkedlist<%s>" % ( empty, self.itype ) class qmapprinter: "print qmap" class _iterator: def __init__(self, val): self.val = val self.ktype = self.val.type.template_argument(0) self.vtype = self.val.type.template_argument(1) self.data_node = self.val['e']['forward'][0] self.count = 0 def __iter__(self): return self def payload (self): #we can't use qmappayloadnode it's inlined #as workaround take sum of sizeof(members) ret = self.ktype.sizeof ret += self.vtype.sizeof ret += gdb.lookup_type('void').pointer().sizeof #but because of data alignment value can higher #so guess it's aliged sizeof(void*) #todo: find real solution problem ret += ret % gdb.lookup_type('void').pointer().sizeof ret -= gdb.lookup_type('void').pointer().sizeof return ret def concrete (self, data_node): node_type = gdb.lookup_type('qmapnode<%s, %s>' % (self.ktype, self.vtype)).pointer() return (data_node.cast(gdb.lookup_type('char').pointer()) - self.payload()).cast(node_type) def next(self): if self.data_node == self.val['e']: raise stopiteration node = self.concrete(self.data_node).dereference() if self.count % 2 == 0: item = node['key'] else: item = node['value'] self.data_node = node['forward'][0] result = ('[%d]' % self.count, item) self.count = self.count + 1 return result def __init__(self, val, container): self.val = val self.container = container def children(self): return self._iterator(self.val) def to_string(self): if self.val['d']['size'] == 0: empty = "empty " else: empty = "" return "%s%s<%s, %s>" % ( empty, self.container, self.val.type.template_argument(0), self.val.type.template_argument(1) ) def display_hint (self): return 'map' class qhashprinter: "print qhash" class _iterator: def __init__(self, val): self.val = val self.d = self.val['d'] self.ktype = self.val.type.template_argument(0) self.vtype = self.val.type.template_argument(1) self.end_node = self.d.cast(gdb.lookup_type('qhashdata::node').pointer()) self.data_node = self.firstnode() self.count = 0 def __iter__(self): return self def hashnode (self): "casts current qhashdata::node qhashnode , returns result. see qhash::concrete()" return self.data_node.cast(gdb.lookup_type('qhashnode<%s, %s>' % (self.ktype, self.vtype)).pointer()) def firstnode (self): "get first node, see qhashdata::firstnode()." e = self.d.cast(gdb.lookup_type('qhashdata::node').pointer()) #print "qhashdata::firstnode() e %s" % e bucketnum = 0 bucket = self.d['buckets'][bucketnum] #print "qhashdata::firstnode() *bucket %s" % bucket n = self.d['numbuckets'] #print "qhashdata::firstnode() n %s" % n while n: #print "qhashdata::firstnode() in while, n %s" % n; if bucket != e: #print "qhashdata::firstnode() in while, return *bucket %s" % bucket return bucket bucketnum += 1 bucket = self.d['buckets'][bucketnum] #print "qhashdata::firstnode() in while, new bucket %s" % bucket n -= 1 #print "qhashdata::firstnode() return e %s" % e return e def nextnode (self, node): "get nextnode after current, see qhashdata::nextnode()." #print "******************************** nextnode" #print "nextnode: node %s" % node next = node['next'].cast(gdb.lookup_type('qhashdata::node').pointer()) e = next #print "nextnode: next %s" % next if next['next']: #print "nextnode: return next" return next #print "nextnode: node->h %s" % node['h'] #print "nextnode: numbuckets %s" % self.d['numbuckets'] start = (node['h'] % self.d['numbuckets']) + 1 bucketnum = start #print "nextnode: start %s" % start bucket = self.d['buckets'][start] #print "nextnode: bucket %s" % bucket n = self.d['numbuckets'] - start #print "nextnode: n %s" % n while n: #print "nextnode: in while; n %s" % n #print "nextnode: in while; e %s" % e #print "nextnode: in while; *bucket %s" % bucket if bucket != e: #print "nextnode: in while; return bucket %s" % bucket return bucket bucketnum += 1 bucket = self.d['buckets'][bucketnum] n -= 1 #print "nextnode: return e %s" % e return e def next(self): "gdb iteration, first call returns key, second value , jumps next hash node." if self.data_node == self.end_node: raise stopiteration node = self.hashnode() if self.count % 2 == 0: item = node['key'] else: item = node['value'] self.data_node = self.nextnode(self.data_node) self.count = self.count + 1 return ('[%d]' % self.count, item) def __init__(self, val, container): self.val = val self.container = container def children(self): return self._iterator(self.val) def to_string(self): if self.val['d']['size'] == 0: empty = "empty " else: empty = "" return "%s%s<%s, %s>" % ( empty, self.container, self.val.type.template_argument(0), self.val.type.template_argument(1) ) def display_hint (self): return 'map' class qdateprinter: def __init__(self, val): self.val = val def to_string(self): julianday = self.val['jd'] if julianday == 0: return "invalid qdate" # copied qt sources if julianday >= 2299161: # gregorian calendar starting october 15, 1582 # algorithm henry f. fliegel , thomas c. van flandern ell = julianday + 68569; n = (4 * ell) / 146097; ell = ell - (146097 * n + 3) / 4; = (4000 * (ell + 1)) / 1461001; ell = ell - (1461 * i) / 4 + 31; j = (80 * ell) / 2447; d = ell - (2447 * j) / 80; ell = j / 11; m = j + 2 - (12 * ell); y = 100 * (n - 49) + + ell; else: # julian calendar until october 4, 1582 # algorithm asked questions calendars claus toendering julianday += 32082; dd = (4 * julianday + 3) / 1461; ee = julianday - (1461 * dd) / 4; mm = ((5 * ee) + 2) / 153; d = ee - (153 * mm + 2) / 5 + 1; m = mm + 3 - 12 * (mm / 10); y = dd - 4800 + (mm / 10); if y <= 0: --y; return "%d-%02d-%02d" % (y, m, d) class qtimeprinter: def __init__(self, val): self.val = val def to_string(self): ds = self.val['mds'] if ds == -1: return "invalid qtime" msecs_per_hour = 3600000 secs_per_min = 60 msecs_per_min = 60000 hour = ds / msecs_per_hour minute = (ds % msecs_per_hour) / msecs_per_min second = (ds / 1000)%secs_per_min msec = ds % 1000 return "%02d:%02d:%02d.%03d" % (hour, minute, second, msec) class qdatetimeprinter: def __init__(self, val): self.val = val def to_string(self): #val['d'] qdatetimeprivate, reason casting doesn't work #so work around manually adjusting pointer date = self.val['d'].cast(gdb.lookup_type('char').pointer()); date += gdb.lookup_type('int').sizeof #increment qatomicint ref; date = date.cast(gdb.lookup_type('qdate').pointer()).dereference(); time = self.val['d'].cast(gdb.lookup_type('char').pointer()); time += gdb.lookup_type('int').sizeof + gdb.lookup_type('qdate').sizeof #increment qatomicint ref; , qdate date; time = time.cast(gdb.lookup_type('qtime').pointer()).dereference(); return "%s %s" % (date, time) class qurlprinter: def __init__(self, val): self.val = val def to_string(self): try: return self.val['d']['encodedoriginal'] except runtimeerror, error: #if no debug information avaliable qt, try guessing correct address encodedoriginal #problem if qurlprivate members changed, fails offset = gdb.lookup_type('int').sizeof offset += offset % gdb.lookup_type('void').pointer().sizeof #alignment offset += gdb.lookup_type('qstring').sizeof * 6 offset += gdb.lookup_type('qbytearray').sizeof encodedoriginal = self.val['d'].cast(gdb.lookup_type('char').pointer()); encodedoriginal += offset encodedoriginal = encodedoriginal.cast(gdb.lookup_type('qbytearray').pointer()).dereference(); encodedoriginal = encodedoriginal['d']['data'].string() return encodedoriginal class qsetprinter: "print qset" def __init__(self, val): self.val = val class _iterator: def __init__(self, hashiterator): self.hashiterator = hashiterator self.count = 0 def __iter__(self): return self def next(self): if self.hashiterator.data_node == self.hashiterator.end_node: raise stopiteration node = self.hashiterator.hashnode() item = node['key'] self.hashiterator.data_node = self.hashiterator.nextnode(self.hashiterator.data_node) self.count = self.count + 1 return ('[%d]' % (self.count-1), item) def children(self): hashprinter = qhashprinter(self.val['q_hash'], none) hashiterator = hashprinter._iterator(self.val['q_hash']) return self._iterator(hashiterator) def to_string(self): if self.val['q_hash']['d']['size'] == 0: empty = "empty " else: empty = "" return "%sqset<%s>" % ( empty , self.val.type.template_argument(0) ) class qcharprinter: def __init__(self, val): self.val = val def to_string(self): return unichr(self.val['ucs']) def display_hint (self): return 'string' def register_qt4_printers (obj): if obj == none: obj = gdb obj.pretty_printers.append (lookup_function) def lookup_function (val): "look-up , return pretty-printer can print val." # type. type = val.type; # if points reference, reference. if type.code == gdb.type_code_ref: type = type.target () # unqualified type, stripped of typedefs. type = type.unqualified ().strip_typedefs () # type name. typename = type.tag if typename == none: return none # iterate on local dictionary of types determine # if printer registered type. return # instantiation of printer if found. function in pretty_printers_dict: if function.search (typename): return pretty_printers_dict[function] (val) # cannot find pretty printer. return none. return none def build_dictionary (): pretty_printers_dict[re.compile('^qstring$')] = lambda val: qstringprinter(val) pretty_printers_dict[re.compile('^qbytearray$')] = lambda val: qbytearrayprinter(val) pretty_printers_dict[re.compile('^qlist<.*>$')] = lambda val: qlistprinter(val, 'qlist', none) pretty_printers_dict[re.compile('^qstringlist$')] = lambda val: qlistprinter(val, 'qstringlist', 'qstring') pretty_printers_dict[re.compile('^qqueue')] = lambda val: qlistprinter(val, 'qqueue', none) pretty_printers_dict[re.compile('^qvector<.*>$')] = lambda val: qvectorprinter(val, 'qvector') pretty_printers_dict[re.compile('^qstack<.*>$')] = lambda val: qvectorprinter(val, 'qstack') pretty_printers_dict[re.compile('^qlinkedlist<.*>$')] = lambda val: qlinkedlistprinter(val) pretty_printers_dict[re.compile('^qmap<.*>$')] = lambda val: qmapprinter(val, 'qmap') pretty_printers_dict[re.compile('^qmultimap<.*>$')] = lambda val: qmapprinter(val, 'qmultimap') pretty_printers_dict[re.compile('^qhash<.*>$')] = lambda val: qhashprinter(val, 'qhash') pretty_printers_dict[re.compile('^qmultihash<.*>$')] = lambda val: qhashprinter(val, 'qmultihash') pretty_printers_dict[re.compile('^qdate$')] = lambda val: qdateprinter(val) pretty_printers_dict[re.compile('^qtime$')] = lambda val: qtimeprinter(val) pretty_printers_dict[re.compile('^qdatetime$')] = lambda val: qdatetimeprinter(val) pretty_printers_dict[re.compile('^qurl$')] = lambda val: qurlprinter(val) pretty_printers_dict[re.compile('^qset<.*>$')] = lambda val: qsetprinter(val) pretty_printers_dict[re.compile('^qchar$')] = lambda val: qcharprinter(val) pretty_printers_dict = {} build_dictionary () register_qt4_printers (none) end set print pretty 1
when start gdb, error:
gnu gdb (gdb) fedora (7.4.50.20120120-54.fc17) <!-- standard gpl message --> gdb configured "x86_64-redhat-linux-gnu". bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... /home/ben/.gdbinit:19: error in sourced command file: undefined command: "import". try "help".
it appears failing @ first import
statement. doing wrong?
edit:
i have tried adding #!/usr/bin/python
first line , makes no difference. fails same error. location when which python
you haven't called python, add python
start of file. remember script executed in gdb shell, doesn't know should parsed python interpreter unless tell it.
this start , end of mine example:
python import sys sys.path.insert(0, '/home/cmannett85/prettyprinters') ... end
Comments
Post a Comment