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