diff options
Diffstat (limited to 'WebKitTools/gdb')
-rw-r--r-- | WebKitTools/gdb/webcore.py | 171 | ||||
-rw-r--r-- | WebKitTools/gdb/webkit.py | 272 | ||||
-rw-r--r-- | WebKitTools/gdb/wtf.py | 133 |
3 files changed, 276 insertions, 300 deletions
diff --git a/WebKitTools/gdb/webcore.py b/WebKitTools/gdb/webcore.py index 83886f8..8dc4d8e 100644 --- a/WebKitTools/gdb/webcore.py +++ b/WebKitTools/gdb/webcore.py @@ -26,170 +26,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""GDB support for WebKit types. - -Add this to your gdb by amending your ~/.gdbinit as follows: - python - import sys - sys.path.insert(0, "/path/to/tools/gdb/") - import webcore -""" - -import gdb -import struct - -def ustring_to_string(ptr, length=None): - """Convert a pointer to UTF-16 data into a Python Unicode string. - - ptr and length are both gdb.Value objects. - If length is unspecified, will guess at the length.""" - extra = '' - if length is None: - # Try to guess at the length. - for i in xrange(0, 2048): - if int((ptr + i).dereference()) == 0: - length = i - break - if length is None: - length = 256 - extra = u' (no trailing NUL found)' - else: - length = int(length) - - char_vals = [int((ptr + i).dereference()) for i in xrange(length)] - string = struct.pack('H' * length, *char_vals).decode('utf-16', 'replace') - - return string + extra - - -class StringPrinter(object): - "Shared code between different string-printing classes" - def __init__(self, val): - self.val = val - - def display_hint(self): - return 'string' - - -class UCharStringPrinter(StringPrinter): - "Print a UChar*; we must guess at the length" - def to_string(self): - return ustring_to_string(self.val) - - -class WebCoreAtomicStringPrinter(StringPrinter): - "Print a WebCore::AtomicString" - def to_string(self): - return self.val['m_string'] - - -class WebCoreStringPrinter(StringPrinter): - "Print a WebCore::String" - def get_length(self): - if not self.val['m_impl']['m_ptr']: - return 0 - return self.val['m_impl']['m_ptr']['m_length'] - - def to_string(self): - if self.get_length() == 0: - return '(null)' - - return ustring_to_string(self.val['m_impl']['m_ptr']['m_data'], - self.get_length()) - - -class WebCoreQualifiedNamePrinter(StringPrinter): - "Print a WebCore::QualifiedName" - - def __init__(self, val): - super(WebCoreQualifiedNamePrinter, self).__init__(val) - self.prefix_length = 0 - self.length = 0 - if self.val['m_impl']: - self.prefix_printer = WebCoreStringPrinter( - self.val['m_impl']['m_prefix']['m_string']) - self.local_name_printer = WebCoreStringPrinter( - self.val['m_impl']['m_localName']['m_string']) - self.prefix_length = self.prefix_printer.get_length() - if self.prefix_length > 0: - self.length = (self.prefix_length + 1 + - self.local_name_printer.get_length()) - else: - self.length = self.local_name_printer.get_length() - - def get_length(self): - return self.length - - def to_string(self): - if self.get_length() == 0: - return "(null)" - else: - if self.prefix_length > 0: - return (self.prefix_printer.to_string() + ":" + - self.local_name_printer.to_string()) - else: - return self.local_name_printer.to_string() - - - -def lookup_function(val): - """Function used to load pretty printers; will be passed to GDB.""" - lookup_tag = val.type.tag - printers = { - "WebCore::AtomicString": WebCoreAtomicStringPrinter, - "WebCore::String": WebCoreStringPrinter, - "WebCore::QualifiedName": WebCoreQualifiedNamePrinter, - } - name = val.type.tag - if name in printers: - return printers[name](val) - - if val.type.code == gdb.TYPE_CODE_PTR: - name = str(val.type.target().unqualified()) - if name == 'UChar': - return UCharStringPrinter(val) - - return None - - -gdb.pretty_printers.append(lookup_function) - - - -class PrintPathToRootCommand(gdb.Command): - """Command for printing WebKit Node trees. -Usage: printpathtoroot variable_name -""" - - def __init__(self): - super(PrintPathToRootCommand, self).__init__("printpathtoroot", - gdb.COMMAND_SUPPORT, - gdb.COMPLETE_NONE) - - def invoke(self, arg, from_tty): - element_type = gdb.lookup_type('WebCore::Element') - node_type = gdb.lookup_type('WebCore::Node') - frame = gdb.selected_frame() - try: - val = gdb.Frame.read_var(frame, arg) - except: - print "No such variable, or invalid type" - return - - target_type = str(val.type.target().strip_typedefs()) - if target_type == str(node_type): - stack = [] - while val: - stack.append([val, - val.cast(element_type.pointer()).dereference()['m_tagName']]) - val = val.dereference()['m_parent'] - - padding = '' - while len(stack) > 0: - pair = stack.pop() - print padding, pair[1], pair[0] - padding = padding + ' ' - else: - print 'Sorry: I don\'t know how to deal with %s yet.' % target_type - -PrintPathToRootCommand() +# For backward compatibility. +import webkit +print ("webcore.py is deprecated. Please use 'import webkit' instead of " + "'import webcore' in your ~/.gdbinit.") diff --git a/WebKitTools/gdb/webkit.py b/WebKitTools/gdb/webkit.py new file mode 100644 index 0000000..2d3b47a --- /dev/null +++ b/WebKitTools/gdb/webkit.py @@ -0,0 +1,272 @@ +# Copyright (C) 2010, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""GDB support for WebKit types. + +Add this to your gdb by amending your ~/.gdbinit as follows: + python + import sys + sys.path.insert(0, "/path/to/tools/gdb/") + import webkit +""" + +import gdb +import re +import struct + + +def ustring_to_string(ptr, length=None): + """Convert a pointer to UTF-16 data into a Python Unicode string. + + ptr and length are both gdb.Value objects. + If length is unspecified, will guess at the length.""" + extra = '' + if length is None: + # Try to guess at the length. + for i in xrange(0, 2048): + if int((ptr + i).dereference()) == 0: + length = i + break + if length is None: + length = 256 + extra = u' (no trailing NUL found)' + else: + length = int(length) + + char_vals = [int((ptr + i).dereference()) for i in xrange(length)] + string = struct.pack('H' * length, *char_vals).decode('utf-16', 'replace') + + return string + extra + + +class StringPrinter(object): + "Shared code between different string-printing classes" + def __init__(self, val): + self.val = val + + def display_hint(self): + return 'string' + + +class UCharStringPrinter(StringPrinter): + "Print a UChar*; we must guess at the length" + def to_string(self): + return ustring_to_string(self.val) + + +class WTFAtomicStringPrinter(StringPrinter): + "Print a WTF::AtomicString" + def to_string(self): + return self.val['m_string'] + + +class WTFStringPrinter(StringPrinter): + "Print a WTF::String" + def get_length(self): + if not self.val['m_impl']['m_ptr']: + return 0 + return self.val['m_impl']['m_ptr']['m_length'] + + def to_string(self): + if self.get_length() == 0: + return '(null)' + + return ustring_to_string(self.val['m_impl']['m_ptr']['m_data'], + self.get_length()) + + +class WebCoreQualifiedNamePrinter(StringPrinter): + "Print a WebCore::QualifiedName" + + def __init__(self, val): + super(WebCoreQualifiedNamePrinter, self).__init__(val) + self.prefix_length = 0 + self.length = 0 + if self.val['m_impl']: + self.prefix_printer = WTFStringPrinter( + self.val['m_impl']['m_prefix']['m_string']) + self.local_name_printer = WTFStringPrinter( + self.val['m_impl']['m_localName']['m_string']) + self.prefix_length = self.prefix_printer.get_length() + if self.prefix_length > 0: + self.length = (self.prefix_length + 1 + + self.local_name_printer.get_length()) + else: + self.length = self.local_name_printer.get_length() + + def get_length(self): + return self.length + + def to_string(self): + if self.get_length() == 0: + return "(null)" + else: + if self.prefix_length > 0: + return (self.prefix_printer.to_string() + ":" + + self.local_name_printer.to_string()) + else: + return self.local_name_printer.to_string() + + +class WTFVectorPrinter: + """Pretty Printer for a WTF::Vector. + + The output of this pretty printer is similar to the output of std::vector's + pretty printer, which is bundled in gcc. + + Example gdb session should look like: + (gdb) p v + $3 = WTF::Vector of length 7, capacity 16 = {7, 17, 27, 37, 47, 57, 67} + (gdb) set print elements 3 + (gdb) p v + $6 = WTF::Vector of length 7, capacity 16 = {7, 17, 27...} + (gdb) set print array + (gdb) p v + $7 = WTF::Vector of length 7, capacity 16 = { + 7, + 17, + 27 + ... + } + (gdb) set print elements 200 + (gdb) p v + $8 = WTF::Vector of length 7, capacity 16 = { + 7, + 17, + 27, + 37, + 47, + 57, + 67 + } + """ + + class Iterator: + def __init__(self, start, finish): + self.item = start + self.finish = finish + self.count = 0 + + def __iter__(self): + return self + + def next(self): + if self.item == self.finish: + raise StopIteration + count = self.count + self.count += 1 + element = self.item.dereference() + self.item += 1 + return ('[%d]' % count, element) + + def __init__(self, val): + self.val = val + + def children(self): + start = self.val['m_buffer']['m_buffer'] + return self.Iterator(start, start + self.val['m_size']) + + def to_string(self): + return ('%s of length %d, capacity %d' + % ('WTF::Vector', self.val['m_size'], self.val['m_buffer']['m_capacity'])) + + def display_hint(self): + return 'array' + + +def add_pretty_printers(): + pretty_printers_dict = { + re.compile("^WTF::Vector<.*>$"): WTFVectorPrinter, + re.compile("^WTF::AtomicString$"): WTFAtomicStringPrinter, + re.compile("^WTF::String$"): WTFStringPrinter, + re.compile("^WebCore::QualifiedName$"): WebCoreQualifiedNamePrinter, + } + + def lookup_function(val): + """Function used to load pretty printers; will be passed to GDB.""" + type = val.type + if type.code == gdb.TYPE_CODE_REF: + type = type.target() + type = type.unqualified().strip_typedefs() + typename = type.tag + if not typename: + return None + for function, pretty_printer in pretty_printers_dict.items(): + if function.search(typename): + return pretty_printer(val) + + if type.code == gdb.TYPE_CODE_PTR: + name = str(type.target().unqualified()) + if name == 'UChar': + return UCharStringPrinter(val) + return None + + gdb.pretty_printers.append(lookup_function) + + +add_pretty_printers() + + +class PrintPathToRootCommand(gdb.Command): + """Command for printing WebKit Node trees. + + Usage: printpathtoroot variable_name""" + + def __init__(self): + super(PrintPathToRootCommand, self).__init__("printpathtoroot", + gdb.COMMAND_SUPPORT, + gdb.COMPLETE_NONE) + + def invoke(self, arg, from_tty): + element_type = gdb.lookup_type('WebCore::Element') + node_type = gdb.lookup_type('WebCore::Node') + frame = gdb.selected_frame() + try: + val = gdb.Frame.read_var(frame, arg) + except: + print "No such variable, or invalid type" + return + + target_type = str(val.type.target().strip_typedefs()) + if target_type == str(node_type): + stack = [] + while val: + stack.append([val, + val.cast(element_type.pointer()).dereference()['m_tagName']]) + val = val.dereference()['m_parent'] + + padding = '' + while len(stack) > 0: + pair = stack.pop() + print padding, pair[1], pair[0] + padding = padding + ' ' + else: + print 'Sorry: I don\'t know how to deal with %s yet.' % target_type + + +PrintPathToRootCommand() diff --git a/WebKitTools/gdb/wtf.py b/WebKitTools/gdb/wtf.py deleted file mode 100644 index cf4b59b..0000000 --- a/WebKitTools/gdb/wtf.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (C) 2010, Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""GDB support for WebKit WTF types. - -Add this to your gdb by amending your ~/.gdbinit as follows: - python - import sys - sys.path.insert(0, "/path/to/tools/gdb/") - import wtf - -See http://sourceware.org/gdb/current/onlinedocs/gdb/Python.html for GDB's -Python API. -""" - -import gdb -import re - - -class WTFVectorPrinter: - """Pretty Printer for a WTF::Vector. - - The output of this pretty printer is similar to the output of std::vector's - pretty printer, which is bundled in gcc. - - Example gdb session should look like: - (gdb) p v - $3 = WTF::Vector of length 7, capacity 16 = {7, 17, 27, 37, 47, 57, 67} - (gdb) set print elements 3 - (gdb) p v - $6 = WTF::Vector of length 7, capacity 16 = {7, 17, 27...} - (gdb) set print array - (gdb) p v - $7 = WTF::Vector of length 7, capacity 16 = { - 7, - 17, - 27 - ... - } - (gdb) set print elements 200 - (gdb) p v - $8 = WTF::Vector of length 7, capacity 16 = { - 7, - 17, - 27, - 37, - 47, - 57, - 67 - } - """ - - class Iterator: - def __init__(self, start, finish): - self.item = start - self.finish = finish - self.count = 0 - - def __iter__(self): - return self - - def next(self): - if self.item == self.finish: - raise StopIteration - count = self.count - self.count += 1 - element = self.item.dereference() - self.item += 1 - return ('[%d]' % count, element) - - def __init__(self, val): - self.val = val - - def children(self): - start = self.val['m_buffer']['m_buffer'] - return self.Iterator(start, start + self.val['m_size']) - - def to_string(self): - return ('%s of length %d, capacity %d' - % ('WTF::Vector', self.val['m_size'], self.val['m_buffer']['m_capacity'])) - - def display_hint(self): - return 'array' - - -def lookup_function(val): - type = val.type - if type.code == gdb.TYPE_CODE_REF: - type = type.target() - type = type.unqualified().strip_typedefs() - typename = type.tag - if not typename: - return None - for function, pretty_printer in pretty_printers_dict.items(): - if function.search(typename): - return pretty_printer(val) - return None - - -def build_pretty_printers_dict(): - pretty_printers_dict[re.compile('^WTF::Vector<.*>$')] = WTFVectorPrinter - - -pretty_printers_dict = {} - -build_pretty_printers_dict() - -gdb.pretty_printers.append(lookup_function) |