Debugging SpiderMonkey with Archer

December 20, 2010 § 4 Comments

If you’re hacking on SpiderMonkey, the JavaScript engine used in Mozilla Firefox, the debugger can be less than helpful when viewing SpiderMonkey’s data structures:

(gdb) print str
$1 = (JSString *) 0x7ffff680a440
(gdb) print *str
$2 = {mLengthAndFlags = 148, {mChars = 0x7ffff680a450, mLeft = 0x7ffff680a450}, {mInlineStorage = {118, 97, 114, 32}, e = {{mCapacity = 9007688887369846, mParent = 0x20007200610076, mBufferWithInfo = 0x20007200610076}, {mBase = 0x20003d00200078, mRight = 0x20003d00200078}}, externalStringType = 6357110}}
(gdb) print/c str->mChars[0]@(str->mLengthAndFlags / 16)
$4 = {118 'v', 97 'a', 114 'r', 32 ' ', 120 'x', 32 ' ', 61 '=', 32 ' ', 53 '5'}

If you know enough magic, you can make it work, but there’s a lot of clutter, and it’s a distraction from the task at hand.

The Archer Project is a development branch of GDB that you can customize in Python. In particular, you can have Archer automatically call your own Python functions to format particular types of values. I’ve written a set of pretty-printers for SpiderMonkey’s datatypes, so for me the above interaction would go:

(gdb) print str
$1 = 0x7ffff680a440 "var x=5" ATOMIZED
(gdb) print *str
$2 = {mLengthAndFlags = (7 << 4)|FLAT|ATOMIZED, mChars = 0x7ffff680a450, externalStringType = 6357110}

When printing a pointer to a JSString, Archer shows the string’s contents, and any flags (like ATOMIZED). When printing a JSString struct value, Archer omits dead union branches — in this case, most of the members.

Archer applies the pretty-printers whenever it needs to print a value, so, for example, stack traces are legible, too:

(gdb) where 1
#0  js_SetPropertyHelper (cx=0xa8e550, obj=0x7ffff6803048 [Object global], id=$jsid("x"), defineHow=1, vp=0x7fffffffc7f0, strict=0) at ../jsobj.cpp:5367

Here the JSObject pointer and the jsid have been printed in a more helpful way.

At present, I have pretty-printers for:

  • jsval and js::Value
  • JSString, JSString *, JSAtom *, and jsid
  • JSObject *, JSFunction *, and JSFunction
  • js::PropertyCacheEntry and js::PCVal
  • JSParseNode *, JSDefinition *, JSParseNode, JSDefinition, and JSFunctionBox *
  • js::Shape

You can check out a copy of the current sources using Mercurial:

$ hg clone http://hg.mozilla.org/users/jblandy_mozilla.com/archer-mozilla
destination directory: archer-mozilla
requesting all changes
...
22 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd archer-mozilla
$ more README

This creates a directory called archer-mozilla; the README file there explains how to make Archer use the pretty-printers.

This is very much a work in progress; there are certainly bugs, and while there are regression tests, they don’t cover all the pretty-printers the package defines. Please let me know if you find a bug, or have suggestions for improvements.

I use Archer on Linux; I don’t know how well it works on Macintosh OS X or Windows. I hear that these pretty-printers can be used with modern stock GDB releases.

§ 4 Responses to Debugging SpiderMonkey with Archer

Leave a comment

What’s this?

You are currently reading Debugging SpiderMonkey with Archer at It Could Be So Much Better.

meta