From eb303585cb38c7bbea7e7d7cafab4d0ea0884023 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sun, 22 Jul 2012 14:57:29 +0100 Subject: GDB: Handy commands for debugging DOM nodes dom node show somenodeptr dom node walk somenodeptr dom document show somedocptr Load with 'source /path/to/libdom/gdb/libdom.py' when inside gdb. --- gdb/libdom.py | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 gdb/libdom.py (limited to 'gdb') diff --git a/gdb/libdom.py b/gdb/libdom.py new file mode 100644 index 0000000..65286e3 --- /dev/null +++ b/gdb/libdom.py @@ -0,0 +1,157 @@ +# LibDOM related commands and utilities for gdb + +import gdb + +def dom_get_type_ptr(typename): + return gdb.lookup_type(typename).pointer() + +def dom_node_at(ptr): + nodetype = dom_get_type_ptr("dom_node_internal") + return ptr.cast(nodetype).dereference() + +def dom_document_at(ptr): + doctype = dom_get_type_ptr("dom_document") + return ptr.cast(doctype).dereference() + +def dom_node_type(node): + return node["type"] + +def dom_node_refcnt(node): + return node["base"]["refcnt"] + +def lwc_string_value(strptr): + cptr = strptr+1 + charptr = cptr.cast(dom_get_type_ptr("char")) + return charptr.string() + +def dom_string__is_intern(intstr): + return str(intstr['type']) == "DOM_STRING_INTERNED" + +def cdata_string_value(cdata): + cptr = cdata['ptr'] + charptr = cptr.cast(dom_get_type_ptr("char")) + return charptr.string() + +def dom_string_value(stringptr): + intstr = stringptr.cast(dom_get_type_ptr("dom_string_internal")).dereference() + if intstr.address == gdb.parse_and_eval("(dom_string_internal*)0"): + return "" + if dom_string__is_intern(intstr): + return lwc_string_value(intstr['data']['intern']) + else: + return cdata_string_value(intstr['data']['cdata']) + +def dom_node_name(node): + namestr = node["name"] + return " '%s'" % dom_string_value(namestr) + +def dom_node_pending_offset(): + return gdb.parse_and_eval("(int)&((struct dom_node_internal *)0)->pending_list") + +def dom_print_node(node, prefix = ""): + print("%s%s @ %s [%s]%s" % (prefix, dom_node_type(node), + node.address, dom_node_refcnt(node), + dom_node_name(node))) + +def dom_walk_tree(node, prefix = ""): + dom_print_node(node, prefix) + current = node['first_child'].dereference() + while current.address != 0: + dom_walk_tree(current, "%s " % prefix) + current = current['next'].dereference() + +def dom_document_show(doc): + print "Node Tree:" + node = dom_node_at(doc.address) + dom_walk_tree(node, " ") + pending = doc['pending_nodes'] + if pending['next'] != pending.address: + print "Pending Node trees:" + current_list_entry = pending['next'] + while current_list_entry is not None: + voidp = current_list_entry.cast(dom_get_type_ptr("void")) + voidp = voidp - dom_node_pending_offset() + node = dom_node_at(voidp) + dom_walk_tree(node, " ") + current_list_entry = node['pending_list']['next'] + if current_list_entry == pending.address: + current_list_entry = None + + +class DOMCommand(gdb.Command): + """DOM related commands""" + + def __init__(self): + gdb.Command.__init__(self, "dom", gdb.COMMAND_DATA, + gdb.COMPLETE_COMMAND, True) + +class DOMNodeCommand(gdb.Command): + """DOMNode related commands""" + + def __init__(self): + gdb.Command.__init__(self, "dom node", gdb.COMMAND_DATA, + gdb.COMPLETE_COMMAND, True) + +class DOMDocumentCommand(gdb.Command): + """DOMDocument related commands""" + + def __init__(self): + gdb.Command.__init__(self, "dom document", gdb.COMMAND_DATA, + gdb.COMPLETE_COMMAND, True) + +class DOMNodeShowCommand(gdb.Command): + """Show a node at a given address.""" + + def __init__(self): + gdb.Command.__init__(self, "dom node show", gdb.COMMAND_DATA, + gdb.COMPLETE_NONE, True) + + def invoke(self, arg, from_tty): + args = gdb.string_to_argv(arg) + self._invoke(*args) + + def _invoke(self, nodeptr): + _ptr = gdb.parse_and_eval(nodeptr) + node = dom_node_at(_ptr) + dom_print_node(node) + +class DOMNodeWalkCommand(gdb.Command): + """Walk a node tree at a given address.""" + + def __init__(self): + gdb.Command.__init__(self, "dom node walk", gdb.COMMAND_DATA, + gdb.COMPLETE_NONE, True) + + def invoke(self, arg, from_tty): + args = gdb.string_to_argv(arg) + self._invoke(*args) + + def _invoke(self, nodeptr): + _ptr = gdb.parse_and_eval(nodeptr) + node = dom_node_at(_ptr) + dom_walk_tree(node) + +class DOMDocumentShowCommand(gdb.Command): + """Show a document at a given address.""" + + def __init__(self): + gdb.Command.__init__(self, "dom document show", gdb.COMMAND_DATA, + gdb.COMPLETE_NONE, True) + + def invoke(self, arg, from_tty): + args = gdb.string_to_argv(arg) + self._invoke(*args) + + def _invoke(self, docptr): + _ptr = gdb.parse_and_eval(docptr) + doc = dom_document_at(_ptr) + dom_document_show(doc) + +DOMCommand() + +DOMNodeCommand() +DOMNodeShowCommand() +DOMNodeWalkCommand() + +DOMDocumentCommand() +DOMDocumentShowCommand() -- cgit v1.2.3