diff options
author | Jack Moffitt <jack@metajack.im> | 2014-08-28 09:34:23 -0600 |
---|---|---|
committer | Jack Moffitt <jack@metajack.im> | 2014-09-08 20:21:42 -0600 |
commit | c6ab60dbfc6da7b4f800c9e40893c8b58413960c (patch) | |
tree | d1d74076cf7fa20e4f77ec7cb82cae98b67362cb /etc/servo_gdb.py | |
parent | db2f642c32fc5bed445bb6f2e45b0f6f0b4342cf (diff) | |
download | servo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.tar.gz servo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.zip |
Cargoify servo
Diffstat (limited to 'etc/servo_gdb.py')
-rw-r--r-- | etc/servo_gdb.py | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/etc/servo_gdb.py b/etc/servo_gdb.py new file mode 100644 index 00000000000..98d9639e7f3 --- /dev/null +++ b/etc/servo_gdb.py @@ -0,0 +1,141 @@ +# Copyright 2013 The Servo Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# A set of simple pretty printers for gdb to make debugging Servo a bit easier. + +# To load these, you need to add something like the following +# to your .gdbinit file. +#python +#import sys +#sys.path.insert(0, '/home/<path to git checkout>/servo/src/etc') +#import servo_gdb +#servo_gdb.register_printers(None) +#end + +import gdb + +# Print Au in both raw value and CSS pixels +class AuPrinter: + def __init__(self, val): + self.val = val + + def to_string(self): + i32_type = gdb.lookup_type("i32") + au = self.val.cast(i32_type); + return "{0}px ({1} au)".format(au / 60.0, au) + +# Print a U8 bitfield as binary +class BitFieldU8Printer: + def __init__(self, val): + self.val = val + + def to_string(self): + u8_type = gdb.lookup_type("u8") + value = self.val.cast(u8_type); + return "[{0:#010b}]".format(int(value)) + +# Print a struct with fields as children +class ChildPrinter: + def __init__(self, val): + self.val = val + + def children(self): + children = [] + for f in self.val.type.fields(): + children.append( (f.name, self.val[f.name]) ) + return children + + def to_string(self): + return None + +# Allow a trusted node to be dereferenced in the debugger +class TrustedNodeAddressPrinter: + def __init__(self, val): + self.val = val + + def children(self): + node_type = gdb.lookup_type("struct script::dom::node::Node").pointer() + value = self.val.cast(node_type) + return [('Node', value)] + + def to_string(self): + return self.val.address + +# Extract a node type ID from enum +class NodeTypeIdPrinter: + def __init__(self, val): + self.val = val + + def to_string(self): + u8_ptr_type = gdb.lookup_type("u8").pointer() + enum_0 = self.val.address.cast(u8_ptr_type).dereference() + enum_type = self.val.type.fields()[int(enum_0)].type; + return str(enum_type).lstrip('struct ') + +# Printer for std::Option<> +class OptionPrinter: + def __init__(self, val): + self.val = val + + def is_some(self): + # Get size of discriminator + d_size = self.val.type.fields()[0].type.sizeof + + if d_size > 0 and d_size <= 8: + # Read first byte to check if None or Some + ptr = self.val.address.cast(gdb.lookup_type("unsigned char").pointer()) + discriminator = int(ptr.dereference()) + return discriminator != 0 + + raise "unhandled discriminator size" + + def children(self): + if self.is_some(): + option_type = self.val.type + + # Get total size and size of value + ptr = self.val.address.cast(gdb.lookup_type("unsigned char").pointer()) + t_size = option_type.sizeof + value_type = option_type.fields()[1].type.fields()[1].type + v_size = value_type.sizeof + data_ptr = (ptr + t_size - v_size).cast(value_type.pointer()).dereference() + return [('Some', data_ptr)] + return [('None', None)] + + def to_string(self): + return None + +# Useful for debugging when type is unknown +class TestPrinter: + def __init__(self, val): + self.val = val + + def to_string(self): + return "[UNKNOWN - type = {0}]".format(str(self.val.type)) + +type_map = [ + ('Au', AuPrinter), + ('FlowFlags', BitFieldU8Printer), + ('IntrinsicWidths', ChildPrinter), + ('PlacementInfo', ChildPrinter), + ('TrustedNodeAddress', TrustedNodeAddressPrinter), + ('NodeTypeId', NodeTypeIdPrinter), + ('Option', OptionPrinter), +] + +def lookup_servo_type (val): + val_type = str(val.type) + for (type_name, printer) in type_map: + if val_type == type_name or val_type.endswith("::"+type_name): + return printer(val) + return None + #return TestPrinter(val) + +def register_printers(obj): + gdb.pretty_printers.append(lookup_servo_type) |