Bug 959445 - Add lldb summaries for nsIAtoms, nsTextNodes and nsTextFragments showing their text content. r=ehsan
--- 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