Skip to content
Snippets Groups Projects
Select Git revision
  • debian/latest default protected
  • pristine-tar protected
  • upstream/latest protected
  • debian/trixie protected
  • wip/trixie-pu
  • debian/bookworm protected
  • origin/wip/bookworm-pu
  • wip/bookworm-pu
  • debian/forky protected
  • wip/2.84.4
  • upstream/2.84.x protected
  • ubuntu/jammy
  • wip/2.84.2
  • ubuntu/plucky
  • wip/2.84.0
  • wip/smcv/dh-auto-test
  • upstream/2.82.x protected
  • debian/bookworm-proposed protected
  • ubuntu/oracular
  • wip/bug1078929
  • debian/2.85.4-1
  • upstream/2.85.4
  • debian/2.85.3-1
  • debian/2.84.4-3_deb13u1
  • debian/2.74.6-2+deb12u7
  • debian/2.84.4-3
  • debian/2.84.4-2
  • upstream/2.85.3
  • debian/2.84.4-1
  • upstream/2.84.4
  • debian/2.85.2-2
  • debian/2.85.2-1
  • upstream/2.85.2
  • debian/2.85.1-2
  • debian/2.85.1-1
  • upstream/2.85.1
  • ubuntu/2.72.4-0ubuntu2.6
  • debian/2.84.3-1
  • upstream/2.84.3
  • debian/2.84.2-1
40 results

glib.py

Blame
  • user avatar
    Dan Vrátil authored
    7678b107
    History
    glib.py 7.07 KiB
    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
        val = read_global_var ("g_quarks")
        max_q = long(read_global_var ("g_quark_seq_id"))
        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 ()