Bug 959445 - Add lldb summaries for nsIAtoms, nsTextNodes and nsTextFragments showing their text content. r=ehsan
authorCameron McCormack <cam@mcc.id.au>
Wed, 15 Jan 2014 11:29:36 +1100
changeset 167690 bb7af8904cac445e8d044d2e5b49748c64ec24a9
parent 167689 a26c945e9a5c9e6bd5ebd4d668e97ec5cfa20316
child 167691 cd6c3a4beacd3bcd8c818caa4cd0f9c2d93cf282
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-esr52@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs959445
milestone29.0a1
Bug 959445 - Add lldb summaries for nsIAtoms, nsTextNodes and nsTextFragments showing their text content. r=ehsan
.lldbinit
python/lldbutils/lldbutils/__init__.py
python/lldbutils/lldbutils/content.py
python/lldbutils/lldbutils/utils.py
--- a/.lldbinit
+++ b/.lldbinit
@@ -9,8 +9,14 @@ settings set target.inline-breakpoint-st
 # will show a variable declared as "nsIFrame *" that points to an nsBlockFrame
 # object as being of type "nsBlockFrame *" rather than "nsIFrame *".
 settings set target.prefer-dynamic-value run-target
 
 # Import the module that defines complex Gecko debugging commands.  Rather
 # than do any kind of searching, this assumes that you are running lldb from
 # the top level source directory.
 script sys.path.append('python/lldbutils'); import lldbutils; lldbutils.init()
+
+# Show the string value in atoms.
+type summary add nsIAtom --summary-string "${var.mString}"
+
+# Show the value of text nodes.
+type summary add nsTextNode --summary-string "${var.mText}"
--- a/python/lldbutils/lldbutils/__init__.py
+++ b/python/lldbutils/lldbutils/__init__.py
@@ -1,7 +1,13 @@
 import lldb
 
-__all__ = ['layout']
+__all__ = ['content', 'layout', 'utils']
 
 def init():
     for name in __all__:
-        __import__('lldbutils.' + name, globals(), locals(), ['init']).init(lldb.debugger)
+        init = None
+        try:
+            init = __import__('lldbutils.' + name, globals(), locals(), ['init']).init
+        except AttributeError:
+            pass
+        if init:
+            init(lldb.debugger)
new file mode 100644
--- /dev/null
+++ b/python/lldbutils/lldbutils/content.py
@@ -0,0 +1,16 @@
+import lldb
+from lldbutils import utils
+
+def summarize_text_fragment(valobj, internal_dict):
+    content_union = valobj.GetChildAtIndex(0)
+    state_union = valobj.GetChildAtIndex(1).GetChildMemberWithName("mState")
+    length = state_union.GetChildMemberWithName("mLength").GetValueAsUnsigned(0)
+    if state_union.GetChildMemberWithName("mIs2b").GetValueAsUnsigned(0):
+        field = "m2b"
+    else:
+        field = "m1b"
+    ptr = content_union.GetChildMemberWithName(field)
+    return utils.format_string(ptr, length)
+
+def init(debugger):
+    debugger.HandleCommand("type summary add nsTextFragment -F lldbutils.content.summarize_text_fragment")
new file mode 100644
--- /dev/null
+++ b/python/lldbutils/lldbutils/utils.py
@@ -0,0 +1,58 @@
+def format_char(c):
+    if c == 0:
+        return "\\0"
+    elif c == 0x07:
+        return "\\a"
+    elif c == 0x08:
+        return "\\b"
+    elif c == 0x0c:
+        return "\\f"
+    elif c == 0x0a:
+        return "\\n"
+    elif c == 0x0d:
+        return "\\r"
+    elif c == 0x09:
+        return "\\t"
+    elif c == 0x0b:
+        return "\\v"
+    elif c == 0x5c:
+        return "\\"
+    elif c == 0x22:
+        return "\\\""
+    elif c == 0x39:
+        return "\\'"
+    elif c < 0x20 or c >= 0x80 and c <= 0xff:
+        return "\\x%02x" % c
+    elif c >= 0x0100:
+        return "\\u%04x" % c
+    else:
+        return chr(c)
+
+# Take an SBValue that is either a char* or char16_t* and formats it like lldb
+# would when printing it.
+def format_string(lldb_value, length=100):
+    ptr = lldb_value.GetValueAsUnsigned(0)
+    char_type = lldb_value.GetType().GetPointeeType()
+    if char_type.GetByteSize() == 1:
+        s = "\""
+        size = 1
+        mask = 0xff
+    elif char_type.GetByteSize() == 2:
+        s = "u\""
+        size = 2
+        mask = 0xffff
+    else:
+        return "(cannot format string with char type %s)" % char_type.GetName()
+    i = 0
+    terminated = False
+    while i < length:
+        c = lldb_value.CreateValueFromAddress("x", ptr + i * size, char_type).GetValueAsUnsigned(0) & mask
+        if c == 0:
+            terminated = True
+            break
+        s += format_char(c)
+        i = i + 1
+    s += "\""
+    if not terminated and i != length:
+        s += "..."
+    return s