diff options
author | JNDTUHH <jndiercks@gmail.com> | 2018-01-14 18:17:10 +0100 |
---|---|---|
committer | JNDTUHH <jndiercks@gmail.com> | 2018-01-14 18:17:10 +0100 |
commit | 70b62a800343f7ced7b34c19b122436e7cfd27d7 (patch) | |
tree | 496b3fe857f91027befee24c8731317089ab902e /Release/share/glib-2.0/gdb/glib.py | |
parent | 9d46c7e44b0c8e0625894dbb688e9b2804d83c9d (diff) |
Update
Diffstat (limited to 'Release/share/glib-2.0/gdb/glib.py')
-rw-r--r-- | Release/share/glib-2.0/gdb/glib.py | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/Release/share/glib-2.0/gdb/glib.py b/Release/share/glib-2.0/gdb/glib.py new file mode 100644 index 0000000..de763ae --- /dev/null +++ b/Release/share/glib-2.0/gdb/glib.py @@ -0,0 +1,257 @@ +import gdb + +# This is not quite right, as local vars may override symname +def read_global_var (symname): + return gdb.selected_frame().read_var(symname) + +def g_quark_to_string (quark): + if quark == None: + return None + quark = long(quark) + if quark == 0: + return None + try: + val = read_global_var ("quarks") + max_q = long(read_global_var ("quark_seq_id")) + except: + try: + val = read_global_var ("g_quarks") + max_q = long(read_global_var ("g_quark_seq_id")) + except: + return None; + if quark < max_q: + return val[quark].string() + return None + +# We override the node printers too, so that node->next is not expanded +class GListNodePrinter: + "Prints a GList node" + + def __init__ (self, val): + self.val = val + + def to_string (self): + return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"])) + +class GSListNodePrinter: + "Prints a GSList node" + + def __init__ (self, val): + self.val = val + + def to_string (self): + return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"])) + +class GListPrinter: + "Prints a GList" + + class _iterator: + def __init__(self, head, listtype): + self.link = head + self.listtype = listtype + self.count = 0 + + def __iter__(self): + return self + + def next(self): + if self.link == 0: + raise StopIteration + data = self.link['data'] + self.link = self.link['next'] + count = self.count + self.count = self.count + 1 + return ('[%d]' % count, data) + + def __init__ (self, val, listtype): + self.val = val + self.listtype = listtype + + def children(self): + return self._iterator(self.val, self.listtype) + + def to_string (self): + return "0x%x" % (long(self.val)) + + def display_hint (self): + return "array" + +class GHashPrinter: + "Prints a GHashTable" + + class _iterator: + def __init__(self, ht, keys_are_strings): + self.ht = ht + if ht != 0: + self.keys = ht["keys"] + self.values = ht["values"] + self.hashes = ht["hashes"] + self.size = ht["size"] + self.pos = 0 + self.keys_are_strings = keys_are_strings + self.value = None + + def __iter__(self): + return self + + def next(self): + if self.ht == 0: + raise StopIteration + if self.value != None: + v = self.value + self.value = None + return v + while long(self.pos) < long(self.size): + self.pos = self.pos + 1 + if long (self.hashes[self.pos]) >= 2: + key = self.keys[self.pos] + val = self.values[self.pos] + + if self.keys_are_strings: + key = key.cast (gdb.lookup_type("char").pointer()) + + # Queue value for next result + self.value = ('[%dv]'% (self.pos), val) + + # Return key + return ('[%dk]'% (self.pos), key) + raise StopIteration + + def __init__ (self, val): + self.val = val + self.keys_are_strings = False + try: + string_hash = read_global_var ("g_str_hash") + except: + string_hash = None + if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash: + self.keys_are_strings = True + + def children(self): + return self._iterator(self.val, self.keys_are_strings) + + def to_string (self): + return "0x%x" % (long(self.val)) + + def display_hint (self): + return "map" + +def pretty_printer_lookup (val): + if is_g_type_instance (val): + return GTypePrettyPrinter (val) + +def pretty_printer_lookup (val): + # None yet, want things like hash table and list + + type = val.type.unqualified() + + # If it points to a reference, get the reference. + if type.code == gdb.TYPE_CODE_REF: + type = type.target () + + if type.code == gdb.TYPE_CODE_PTR: + type = type.target().unqualified() + t = str(type) + if t == "GList": + return GListPrinter(val, "GList") + if t == "GSList": + return GListPrinter(val, "GSList") + if t == "GHashTable": + return GHashPrinter(val) + else: + t = str(type) + if t == "GList": + return GListNodePrinter(val) + if t == "GSList *": + return GListPrinter(val, "GSList") + return None + +def register (obj): + if obj == None: + obj = gdb + + obj.pretty_printers.append(pretty_printer_lookup) + +class ForeachCommand (gdb.Command): + """Foreach on list""" + + def __init__ (self): + super (ForeachCommand, self).__init__ ("gforeach", + gdb.COMMAND_DATA, + gdb.COMPLETE_SYMBOL) + + def valid_name (self, name): + if not name[0].isalpha(): + return False + return True + + def parse_args (self, arg): + i = arg.find(" ") + if i <= 0: + raise Exception ("No var specified") + var = arg[:i] + if not self.valid_name(var): + raise Exception ("Invalid variable name") + + while i < len (arg) and arg[i].isspace(): + i = i + 1 + + if arg[i:i+2] != "in": + raise Exception ("Invalid syntax, missing in") + + i = i + 2 + + while i < len (arg) and arg[i].isspace(): + i = i + 1 + + colon = arg.find (":", i) + if colon == -1: + raise Exception ("Invalid syntax, missing colon") + + val = arg[i:colon] + + colon = colon + 1 + while colon < len (arg) and arg[colon].isspace(): + colon = colon + 1 + + command = arg[colon:] + + return (var, val, command) + + def do_iter(self, arg, item, command): + item = item.cast (gdb.lookup_type("void").pointer()) + item = long(item) + to_eval = "set $%s = (void *)0x%x\n"%(arg, item) + gdb.execute(to_eval) + gdb.execute(command) + + def slist_iterator (self, arg, container, command): + l = container.cast (gdb.lookup_type("GSList").pointer()) + while long(l) != 0: + self.do_iter (arg, l["data"], command) + l = l["next"] + + def list_iterator (self, arg, container, command): + l = container.cast (gdb.lookup_type("GList").pointer()) + while long(l) != 0: + self.do_iter (arg, l["data"], command) + l = l["next"] + + def pick_iterator (self, container): + t = container.type.unqualified() + if t.code == gdb.TYPE_CODE_PTR: + t = t.target().unqualified() + t = str(t) + if t == "GSList": + return self.slist_iterator + if t == "GList": + return self.list_iterator + raise Exception("Invalid container type %s"%(str(container.type))) + + def invoke (self, arg, from_tty): + (var, container, command) = self.parse_args(arg) + container = gdb.parse_and_eval (container) + func = self.pick_iterator(container) + func(var, container, command) + +ForeachCommand () |