Support for debugging SpiderMonkey with GDB now landed

Jim Blandy

1

The main source tree for Firefox, Mozilla Central, now includes some code that should make debugging SpiderMonkey with GDB on Linux much more pleasant and productive.

GDB understands C++ types and values, but naturally it has no idea what the debuggee intends them to represent. As a result, GDB’s attempts to display those values can sometimes be worse than printing nothing at all. For example, here’s how a stock GDB displays a stack frame for a call to js::baseops::SetPropertyHelper:

(gdb) frame
#0 js::baseops::SetPropertyHelper (cx=0xc648b0, obj={<js::HandleBase> = {}, ptr = 0x7fffffffc960}, receiver={<js::HandleBase> = {}, ptr = 0x7fffffffc960}, id={<js::HandleBase> = {}, ptr = 0x7fffffffc1e0}, defineHow=4, vp={<js::MutableHandleBase> = {<js::MutableValueOperations<JS::MutableHandle >> = {<js::ValueOperations<JS::MutableHandle >> = {}, }, }, ptr = 0x7fffffffc1f0}, strict=0) at /home/jimb/moz/dbg/js/src/jsobj.cpp:3593

There exist people who can pick through that, but for me it’s just a pile of hexadecimal noise. And yet, if you persevere, what those arguments represent is quite simple: in this case, obj and receiver are both the JavaScript global object; id is the identifier "x"; and vp refers to the JavaScript string value "foo". This SetPropertyHelper call is simply storing "foo" as the value of the global variable x. But it sure is hard to tell—and that’s an annoyance for SpiderMonkey developers.

As of early December, Mozilla Central includes Python scripts for GDB that define custom printers for SpiderMonkey types, so that when GDB comes across a SpiderMonkey type like MutableValueHandle, it can print it in a meaningful way. With these changes, GDB displays the stack frame shown above like this:

(gdb) frame
#0 js::baseops::SetPropertyHelper (cx=0xc648b0, obj=(JSObject * const) 0x7ffff151f060 [object global] delegate, receiver=(JSObject * const) 0x7ffff151f060 [object global] delegate, id=$jsid("x"), defineHow=4, vp=$jsval("foo"), strict=0) at /home/jimb/moz/dbg/js/src/jsobj.cpp:3593

Here it’s much easier to see what’s going on. Objects print with their class, like “global” or “Object”; strings print as strings; jsval values print as appropriate for their tags; and so on. (The line breaks could still be improved, but that’s GDB for you.)

Naturally, the pretty-printers work with any command in GDB that displays values: print, backtrace, display, and so on. Each type requires custom Python code to decode it; at present we have pretty-printers for JSObject, JSString, jsval, the various Rooted and Handle types, and things derived from those. The list will grow.

GDB picks up the SpiderMonkey support scripts automatically when you’re debugging the JavaScript shell, as directed by the js-gdb.py file that the build system places in the same directory as the js executable. We haven’t yet made the support scripts load automatically when debugging Firefox, as that’s a much larger audience of developers, and we’d like a chance to shake out bugs before foisting it on everyone.

Some versions of GDB are patched to trust only auto-load files found in directories you’ve whitelisted; if this is the case for you, GDB will complain, and you’ll need to add a command like the following to your ~/.gdbinit file:

# Tell GDB to trust auto-load files found under ~/moz.
add-auto-load-safe-path ~/moz

If you need to see a value in its plain C++ form, with no pretty-printing applied, you can add the /r format modifier to the print command:

(gdb) print vp
$1 = $jsval("foo")
(gdb) print/r vp
$2 = {
  <js::MutableHandleBase> = {
    <js::MutableValueOperations<JS::MutableHandle >> = {
      <js::ValueOperations<JS::MutableHandle >> = {}, }, },
  members of JS::MutableHandle:
  ptr = 0x7fffffffc1f0
}

If you run into troubles with a pretty-printer, please file a bug in Bugzilla, under the “Core” product, for the “JavaScript Engine” component. (The pretty-printers have their own unit and regression tests; we do want them to be reliable.) In the mean time, you can disable the pretty-printers with the disable pretty-printer command:

(gdb) disable pretty-printer .* SpiderMonkey
12 printers disabled
128 of 140 printers enabled

For more details, see the GDB support directory’s README file.

One response

Post a comment

  1. Question wrote on :

    Will there be a post on asm.js?
    Oh, and when I try to post a comment, Firefox threows a security warning: “even though this page is secure, information sent will not be encrypted” or whatever the English message is. Had to put ‘s’ in http:// using Firebug. :)

    Reply

Post Your Comment

  1.