mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
221
python/lldbutils/README.txt
Normal file
221
python/lldbutils/README.txt
Normal 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"
|
||||
|
||||
13
python/lldbutils/lldbutils/__init__.py
Normal file
13
python/lldbutils/lldbutils/__init__.py
Normal 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)
|
||||
21
python/lldbutils/lldbutils/content.py
Normal file
21
python/lldbutils/lldbutils/content.py
Normal 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")
|
||||
105
python/lldbutils/lldbutils/general.py
Normal file
105
python/lldbutils/lldbutils/general.py
Normal 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")
|
||||
130
python/lldbutils/lldbutils/gfx.py
Normal file
130
python/lldbutils/lldbutils/gfx.py
Normal 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")
|
||||
20
python/lldbutils/lldbutils/layout.py
Normal file
20
python/lldbutils/lldbutils/layout.py
Normal 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');
|
||||
70
python/lldbutils/lldbutils/utils.py
Normal file
70
python/lldbutils/lldbutils/utils.py
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue