import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

221
python/lldbutils/README.txt Normal file
View file

@ -0,0 +1,221 @@
lldb debugging functionality for Gecko
======================================
This directory contains a module, lldbutils, which is imported by the
in-tree .lldbinit file. The lldbutil modules define some lldb commands
that are handy for debugging Gecko.
If you want to add a new command or Python-implemented type summary, either add
it to one of the existing broad area Python files (such as lldbutils/layout.py
for layout-related commands) or create a new file if none of the existing files
is appropriate. If you add a new file, make sure you add it to __all__ in
lldbutils/__init__.py.
Supported commands
------------------
Most commands below that can take a pointer to an object also support being
called with a smart pointer like nsRefPtr or nsCOMPtr.
* frametree EXPR, ft EXPR
frametreelimited EXPR, ftl EXPR
Shows information about a frame tree. EXPR is an expression that
is evaluated, and must be an nsIFrame*. frametree displays the
entire frame tree that contains the given frame. frametreelimited
displays a subtree of the frame tree rooted at the given frame.
(lldb) p this
(nsBlockFrame *) $4 = 0x000000011687fcb8
(lldb) ftl this
Block(div)(-1)@0x11687fcb8 {0,0,7380,690} [state=0002100000d04601] [content=0x11688c0c0] [sc=0x11687f990:-moz-scrolled-content]<
line 0x116899130: count=1 state=inline,clean,prevmarginclean,not impacted,not wrapped,before:nobr,after:nobr[0x100] {60,0,0,690} vis-overflow=60,510,0,0 scr-overflow=60,510,0,0 <
Text(0)""@0x1168990c0 {60,510,0,0} [state=0001000020404000] [content=0x11687ca10] [sc=0x11687fd88:-moz-non-element,parent=0x11687eb00] [run=0x115115e80][0,0,T]
>
>
(lldb) ft this
Viewport(-1)@0x116017430 [view=0x115efe190] {0,0,60,60} [state=000b063000002623] [sc=0x1160170f8:-moz-viewport]<
HTMLScroll(html)(-1)@0x1160180d0 {0,0,0,0} [state=000b020000000403] [content=0x115e4d640] [sc=0x116017768:-moz-viewport-scroll]<
...
Canvas(html)(-1)@0x116017e08 {0,0,60,60} vis-overflow=0,0,8340,2196 scr-overflow=0,0,8220,2196 [state=000b002000000601] [content=0x115e4d640] [sc=0x11687e0f8:-moz-scrolled-canvas]<
Block(html)(-1)@0x11687e578 {0,0,60,2196} vis-overflow=0,0,8340,2196 scr-overflow=0,0,8220,2196 [state=000b100000d00601] [content=0x115e4d640] [sc=0x11687e4b8,parent=0x0]<
line 0x11687ec48: count=1 state=block,clean,prevmarginclean,not impacted,not wrapped,before:nobr,after:nobr[0x48] bm=480 {480,480,0,1236} vis-overflow=360,426,7980,1410 scr-overflow=480,480,7740,1236 <
Block(body)(1)@0x11687ebb0 {480,480,0,1236} vis-overflow=-120,-54,7980,1410 scr-overflow=0,0,7740,1236 [state=000b120000100601] [content=0x115ed8980] [sc=0x11687e990]<
line 0x116899170: count=1 state=inline,clean,prevmarginclean,not impacted,not wrapped,before:nobr,after:nobr[0x0] {0,0,7740,1236} vis-overflow=-120,-54,7980,1410 scr-overflow=0,0,7740,1236 <
nsTextControlFrame@0x11687f068 {0,66,7740,1170} vis-overflow=-120,-120,7980,1410 scr-overflow=0,0,7740,1170 [state=0002000000004621] [content=0x115ca2c50] [sc=0x11687ea40]<
HTMLScroll(div)(-1)@0x11687f6b0 {180,240,7380,690} [state=0002000000084409] [content=0x11688c0c0] [sc=0x11687eb00]<
Block(div)(-1)@0x11687fcb8 {0,0,7380,690} [state=0002100000d04601] [content=0x11688c0c0] [sc=0x11687f990:-moz-scrolled-content]<
line 0x116899130: count=1 state=inline,clean,prevmarginclean,not impacted,not wrapped,before:nobr,after:nobr[0x100] {60,0,0,690} vis-overflow=60,510,0,0 scr-overflow=60,510,0,0 <
Text(0)""@0x1168990c0 {60,510,0,0} [state=0001000020404000] [content=0x11687ca10] [sc=0x11687fd88:-moz-non-element,parent=0x11687eb00] [run=0x115115e80][0,0,T]
...
* js
Dumps the current JS stack.
(lldb) js
0 anonymous(aForce = false) ["chrome://browser/content/browser.js":13414]
this = [object Object]
1 updateAppearance() ["chrome://browser/content/browser.js":13326]
this = [object Object]
2 handleEvent(aEvent = [object Event]) ["chrome://browser/content/tabbrowser.xml":3811]
this = [object XULElement]
* prefcnt EXPR
Shows the refcount of a given object. EXPR is an expression that is
evaluated, and can be either a pointer to or an actual refcounted
object. The object can be a standard nsISupports-like refcounted
object, a cycle-collected object or a mozilla::RefCounted<T> object.
(lldb) p this
(nsHTMLDocument *) $1 = 0x0000000116e9d800
(lldb) prefcnt this
20
(lldb) p mDocumentURI
(nsCOMPtr<nsIURI>) $3 = {
mRawPtr = 0x0000000117163e50
}
(lldb) prefcnt mDocumentURI
11
* pstate EXPR
Shows the frame state bits (using their symbolic names) of a given frame.
EXPR is an expression that is evaluated, and must be an nsIFrame*.
(lldb) p this
(nsTextFrame *) $1 = 0x000000011f470b10
(lldb) p/x mState
(nsFrameState) $2 = 0x0000004080604000
(lldb) pstate this
TEXT_HAS_NONCOLLAPSED_CHARACTERS | TEXT_END_OF_LINE | TEXT_START_OF_LINE | NS_FRAME_PAINTED_THEBES | NS_FRAME_INDEPENDENT_SELECTION
* ptag EXPR
Shows the DOM tag name of a node. EXPR is an expression that is
evaluated, and can be either an nsINode pointer or a concrete DOM
object.
(lldb) p this
(nsHTMLDocument *) $0 = 0x0000000116e9d800
(lldb) ptag this
(PermanentAtomImpl *) $1 = 0x0000000110133ac0 u"#document"
(lldb) p this->GetRootElement()
(mozilla::dom::HTMLSharedElement *) $2 = 0x0000000118429780
(lldb) ptag $2
(PermanentAtomImpl *) $3 = 0x0000000110123b80 u"html"
Supported type summaries and synthetic children
-----------------------------------------------
In lldb terminology, type summaries are rules for how to display a value
when using the "expression" command (or its familiar-to-gdb-users "p" alias),
and synthetic children are fake member variables or array elements also
added by custom rules.
For objects that do have synthetic children defined for them, like nsTArray,
the "expr -R -- EXPR" command can be used to show its actual member variables.
* nsAString, nsACString,
nsFixedString, nsFixedCString,
nsAutoString, nsAutoCString
Strings have a type summary that shows the actual string.
(lldb) frame info
frame #0: 0x000000010400cfea XUL`nsCSSParser::ParseProperty(this=0x00007fff5fbf5248, aPropID=eCSSProperty_margin_top, aPropValue=0x00007fff5fbf53f8, aSheetURI=0x0000000115ae8c00, aBaseURI=0x0000000115ae8c00, aSheetPrincipal=0x000000010ff9e040, aDeclaration=0x00000001826fd580, aChanged=0x00007fff5fbf5247, aIsImportant=false, aIsSVGMode=false) + 74 at nsCSSParser.cpp:12851
(lldb) p aPropValue
(const nsAString_internal) $16 = u"-25px"
(lldb) p this
(nsHTMLDocument *) $18 = 0x0000000115b56000
(lldb) p mContentType
(nsCString) $19 = {
nsACString_internal = "text/html"
}
* nscolor
nscolors (32-bit RGBA colors) have a type summary that shows the color as
one of the CSS 2.1 color keywords, a six digit hex color, an rgba() color,
or the "transparent" keyword.
(lldb) p this
(nsTextFrame *) $0 = 0x00000001168245e0
(lldb) p *this->StyleColor()
(const nsStyleColor) $1 = {
mColor = lime
}
(lldb) expr -R -- *this->StyleColor()
(const nsStyleColor) $2 = {
mColor = 4278255360
}
* nsIAtom
Atoms have a type summary that shows the string value inside the atom.
(lldb) frame info
frame #0: 0x00000001028b8c49 XUL`mozilla::dom::Element::GetBoolAttr(this=0x0000000115ca1c50, aAttr=0x000000011012a640) const + 25 at Element.h:907
(lldb) p aAttr
(PermanentAtomImpl *) $1 = 0x000000011012a640 u"readonly"
* nsTArray and friends
nsTArrays and their auto and fallible varieties have synthetic children
for their elements. This means when displaying them with "expr" (or "p"),
they will be shown like regular arrays, rather than showing the mHdr and
other fields.
(lldb) frame info
frame #0: 0x00000001043eb8a8 XUL`SVGTextFrame::DoGlyphPositioning(this=0x000000012f3f8778) + 248 at SVGTextFrame.cpp:4940
(lldb) p charPositions
(nsTArray<nsPoint>) $5 = {
[0] = {
mozilla::gfx::BasePoint<int, nsPoint> = {
x = 0
y = 816
}
}
[1] = {
mozilla::gfx::BasePoint<int, nsPoint> = {
x = 426
y = 816
}
}
[2] = {
mozilla::gfx::BasePoint<int, nsPoint> = {
x = 906
y = 816
}
}
}
(lldb) expr -R -- charPositions
(nsTArray<nsPoint>) $4 = {
nsTArray_Impl<nsPoint, nsTArrayInfallibleAllocator> = {
nsTArray_base<nsTArrayInfallibleAllocator, nsTArray_CopyWithMemutils> = {
mHdr = 0x000000012f3f1b80
}
}
}
* nsTextNode, nsTextFragment
Text nodes have a type summary that shows the nsTextFragment in the
nsTextNode, which itself has a type summary that shows the text
content.
(lldb) p this
(nsTextFrame *) $14 = 0x000000011811bb10
(lldb) p mContent
(nsTextNode *) $15 = 0x0000000118130110 "Search or enter address"

View file

@ -0,0 +1,13 @@
import lldb
__all__ = ['content', 'general', 'gfx', 'layout', 'utils']
def init():
for name in __all__:
init = None
try:
init = __import__('lldbutils.' + name, globals(), locals(), ['init']).init
except AttributeError:
pass
if init:
init(lldb.debugger)

View file

@ -0,0 +1,21 @@
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 ptag(debugger, command, result, dict):
"""Displays the tag name of a content node."""
debugger.HandleCommand("expr (" + command + ")->mNodeInfo.mRawPtr->mInner.mName")
def init(debugger):
debugger.HandleCommand("type summary add nsTextFragment -F lldbutils.content.summarize_text_fragment")
debugger.HandleCommand("command script add -f lldbutils.content.ptag ptag")

View file

@ -0,0 +1,105 @@
import lldb
from lldbutils import utils
def summarize_string(valobj, internal_dict):
data = valobj.GetChildMemberWithName("mData")
length = valobj.GetChildMemberWithName("mLength").GetValueAsUnsigned(0)
return utils.format_string(data, length)
class TArraySyntheticChildrenProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj
self.header = self.valobj.GetChildMemberWithName("mHdr")
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
self.element_size = self.element_type.GetByteSize()
header_size = self.header.GetType().GetPointeeType().GetByteSize()
self.element_base_addr = self.header.GetValueAsUnsigned(0) + header_size
def num_children(self):
return self.header.Dereference().GetChildMemberWithName("mLength").GetValueAsUnsigned(0)
def get_child_index(self, name):
try:
index = int(name)
if index >= self.num_children():
return None
except:
pass
return None
def get_child_at_index(self, index):
if index >= self.num_children():
return None
addr = self.element_base_addr + index * self.element_size
return self.valobj.CreateValueFromAddress("[%d]" % index, addr, self.element_type)
def prefcnt(debugger, command, result, dict):
"""Displays the refcount of an object."""
# We handled regular nsISupports-like refcounted objects and cycle collected
# objects.
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
obj = frame.EvaluateExpression(command)
if obj.GetError().Fail():
print "could not evaluate expression"
return
obj = utils.dereference(obj)
field = obj.GetChildMemberWithName("mRefCnt")
if field.GetError().Fail():
field = obj.GetChildMemberWithName("refCnt")
if field.GetError().Fail():
print "not a refcounted object"
return
refcnt_type = field.GetType().GetCanonicalType().GetName()
if refcnt_type == "nsAutoRefCnt":
print field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0)
elif refcnt_type == "nsCycleCollectingAutoRefCnt":
print field.GetChildMemberWithName("mRefCntAndFlags").GetValueAsUnsigned(0) >> 2
elif refcnt_type == "mozilla::ThreadSafeAutoRefCnt":
print field.GetChildMemberWithName("mValue").GetChildMemberWithName("mValue").GetValueAsUnsigned(0)
elif refcnt_type == "int": # non-atomic mozilla::RefCounted object
print field.GetValueAsUnsigned(0)
elif refcnt_type == "mozilla::Atomic<int>": # atomic mozilla::RefCounted object
print field.GetChildMemberWithName("mValue").GetValueAsUnsigned(0)
else:
print "unknown mRefCnt type " + refcnt_type
# Used to work around http://llvm.org/bugs/show_bug.cgi?id=22211
def callfunc(debugger, command, result, dict):
"""Calls a function for which debugger information is unavailable by getting its address from the symbol table.
The function is assumed to return void."""
if '(' not in command:
print 'Usage: callfunc your_function(args)'
return
command_parts = command.split('(')
funcname = command_parts[0].strip()
args = command_parts[1]
target = debugger.GetSelectedTarget()
symbols = target.FindFunctions(funcname).symbols
if not symbols:
print 'Could not find a function symbol for a function called "%s"' % funcname
return
sym = symbols[0]
arg_types = '()'
if sym.name and sym.name.startswith(funcname + '('):
arg_types = sym.name[len(funcname):]
debugger.HandleCommand('print ((void(*)%s)0x%0x)(%s' % (arg_types, sym.addr.GetLoadAddress(target), args))
def init(debugger):
debugger.HandleCommand("type summary add nsAString_internal -F lldbutils.general.summarize_string")
debugger.HandleCommand("type summary add nsACString_internal -F lldbutils.general.summarize_string")
debugger.HandleCommand("type summary add nsFixedString -F lldbutils.general.summarize_string")
debugger.HandleCommand("type summary add nsFixedCString -F lldbutils.general.summarize_string")
debugger.HandleCommand("type summary add nsAutoString -F lldbutils.general.summarize_string")
debugger.HandleCommand("type summary add nsAutoCString -F lldbutils.general.summarize_string")
debugger.HandleCommand("type synthetic add -x \"nsTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
debugger.HandleCommand("type synthetic add -x \"AutoTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
debugger.HandleCommand("type synthetic add -x \"FallibleTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
debugger.HandleCommand("command script add -f lldbutils.general.prefcnt -f lldbutils.general.prefcnt prefcnt")
debugger.HandleCommand("command script add -f lldbutils.general.callfunc -f lldbutils.general.callfunc callfunc")

View file

@ -0,0 +1,130 @@
import lldb
def summarize_nscolor(valobj, internal_dict):
colors = {
"#800000": "maroon",
"#ff0000": "red",
"#ffa500": "orange",
"#ffff00": "yellow",
"#808000": "olive",
"#800080": "purple",
"#ff00ff": "fuchsia",
"#ffffff": "white",
"#00ff00": "lime",
"#008000": "green",
"#000080": "navy",
"#0000ff": "blue",
"#00ffff": "aqua",
"#008080": "teal",
"#000000": "black",
"#c0c0c0": "silver",
"#808080": "gray"
}
value = valobj.GetValueAsUnsigned(0)
if value == 0:
return "transparent"
if value & 0xff000000 != 0xff000000:
return "rgba(%d, %d, %d, %f)" % (value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, ((value >> 24) & 0xff) / 255.0)
color = "#%02x%02x%02x" % (value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff)
if color in colors:
return colors[color]
return color
class RegionSyntheticChildrenProvider:
def __init__(self, valobj, internal_dict, rect_type = "nsRect"):
self.rect_type = rect_type
self.valobj = valobj
self.pixman_region = self.valobj.GetChildMemberWithName("mImpl")
self.pixman_data = self.pixman_region.GetChildMemberWithName("data")
self.pixman_extents = self.pixman_region.GetChildMemberWithName("extents")
self.num_rects = self.pixman_region_num_rects()
self.box_type = self.pixman_extents.GetType()
self.box_type_size = self.box_type.GetByteSize()
self.box_list_base_ptr = self.pixman_data.GetValueAsUnsigned(0) + self.pixman_data.GetType().GetPointeeType().GetByteSize()
def pixman_region_num_rects(self):
if self.pixman_data.GetValueAsUnsigned(0):
return self.pixman_data.Dereference().GetChildMemberWithName("numRects").GetValueAsUnsigned(0)
return 1
def num_children(self):
return 2 + self.num_rects
def get_child_index(self, name):
if name == "numRects":
return 0
if name == "bounds":
return 1
return None
def convert_pixman_box_to_rect(self, valobj, name):
x1 = valobj.GetChildMemberWithName("x1").GetValueAsSigned()
x2 = valobj.GetChildMemberWithName("x2").GetValueAsSigned()
y1 = valobj.GetChildMemberWithName("y1").GetValueAsSigned()
y2 = valobj.GetChildMemberWithName("y2").GetValueAsSigned()
return valobj.CreateValueFromExpression(name,
'%s(%d, %d, %d, %d)' % (self.rect_type, x1, y1, x2 - x1, y2 - y1))
def get_child_at_index(self, index):
if index == 0:
return self.pixman_data.CreateValueFromExpression('numRects', '(uint32_t)%d' % self.num_rects)
if index == 1:
return self.convert_pixman_box_to_rect(self.pixman_extents, 'bounds')
rect_index = index - 2
if rect_index >= self.num_rects:
return None
if self.num_rects == 1:
return self.convert_pixman_box_to_rect(self.pixman_extents, 'bounds')
box_address = self.box_list_base_ptr + rect_index * self.box_type_size
box = self.pixman_data.CreateValueFromAddress('', box_address, self.box_type)
return self.convert_pixman_box_to_rect(box, "[%d]" % rect_index)
class IntRegionSyntheticChildrenProvider:
def __init__(self, valobj, internal_dict):
wrapped_region = valobj.GetChildMemberWithName("mImpl")
self.wrapped_provider = RegionSyntheticChildrenProvider(wrapped_region, internal_dict, "nsIntRect")
def num_children(self):
return self.wrapped_provider.num_children()
def get_child_index(self, name):
return self.wrapped_provider.get_child_index(name)
def get_child_at_index(self, index):
return self.wrapped_provider.get_child_at_index(index)
def summarize_rect(valobj, internal_dict):
x = valobj.GetChildMemberWithName("x").GetValue()
y = valobj.GetChildMemberWithName("y").GetValue()
width = valobj.GetChildMemberWithName("width").GetValue()
height = valobj.GetChildMemberWithName("height").GetValue()
return "%s, %s, %s, %s" % (x, y, width, height)
def rect_is_empty(valobj):
width = valobj.GetChildMemberWithName("width").GetValueAsSigned()
height = valobj.GetChildMemberWithName("height").GetValueAsSigned()
return width <= 0 or height <= 0
def summarize_region(valobj, internal_dict):
# This function makes use of the synthetic children generated for ns(Int)Regions.
bounds = valobj.GetChildMemberWithName("bounds")
bounds_summary = summarize_rect(bounds, internal_dict)
num_rects = valobj.GetChildMemberWithName("numRects").GetValueAsUnsigned(0)
if num_rects <= 1:
if rect_is_empty(bounds):
return "empty"
if num_rects == 1:
return "one rect: " + bounds_summary
return str(num_rects) + " rects, bounds: " + bounds_summary
def init(debugger):
debugger.HandleCommand("type summary add nscolor -v -F lldbutils.gfx.summarize_nscolor")
debugger.HandleCommand("type summary add nsRect -v -F lldbutils.gfx.summarize_rect")
debugger.HandleCommand("type summary add nsIntRect -v -F lldbutils.gfx.summarize_rect")
debugger.HandleCommand("type summary add gfxRect -v -F lldbutils.gfx.summarize_rect")
debugger.HandleCommand("type synthetic add nsRegion -l lldbutils.gfx.RegionSyntheticChildrenProvider")
debugger.HandleCommand("type synthetic add nsIntRegion -l lldbutils.gfx.IntRegionSyntheticChildrenProvider")
debugger.HandleCommand("type summary add nsRegion -v -F lldbutils.gfx.summarize_region")
debugger.HandleCommand("type summary add nsIntRegion -v -F lldbutils.gfx.summarize_region")

View file

@ -0,0 +1,20 @@
import lldb
def frametree(debugger, command, result, dict):
"""Dumps the frame tree containing the given nsIFrame*."""
debugger.HandleCommand('expr (' + command + ')->DumpFrameTree()')
def frametreelimited(debugger, command, result, dict):
"""Dumps the subtree of a frame tree rooted at the given nsIFrame*."""
debugger.HandleCommand('expr (' + command + ')->DumpFrameTreeLimited()')
def pstate(debugger, command, result, dict):
"""Displays a frame's state bits symbolically."""
debugger.HandleCommand('expr mozilla::PrintFrameState(' + command + ')')
def init(debugger):
debugger.HandleCommand('command script add -f lldbutils.layout.frametree frametree')
debugger.HandleCommand('command script add -f lldbutils.layout.frametreelimited frametreelimited')
debugger.HandleCommand('command alias ft frametree')
debugger.HandleCommand('command alias ftl frametreelimited')
debugger.HandleCommand('command script add -f lldbutils.layout.pstate pstate');

View file

@ -0,0 +1,70 @@
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 == 0x27:
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
# Dereferences a raw pointer, nsCOMPtr, RefPtr, nsAutoPtr, already_AddRefed or
# mozilla::RefPtr; otherwise returns the value unchanged.
def dereference(lldb_value):
if lldb_value.TypeIsPointerType():
return lldb_value.Dereference()
name = lldb_value.GetType().GetUnqualifiedType().GetName()
if name.startswith("nsCOMPtr<") or name.startswith("RefPtr<") or name.startswith("nsAutoPtr<") or name.startswith("already_AddRefed<"):
return lldb_value.GetChildMemberWithName("mRawPtr")
if name.startswith("mozilla::RefPtr<"):
return lldb_value.GetChildMemberWithName("ptr")
return lldb_value