Closed Bug 1261426 Opened 4 years ago Closed 4 years ago

gdb unwinder reports IOError exceptions when used on core files.

Categories

(Core :: JavaScript Engine, defect)

defect
Not set

Tracking

()

RESOLVED FIXED
mozilla48
Tracking Status
firefox48 --- fixed

People

(Reporter: nbp, Assigned: nbp)

References

Details

Attachments

(3 files)

Currently, when using gdb with the python scripts located in js-gdb.py.  The unwinder is unable to locate the frame, because /proc/<pid>/maps no longer exists.

This feature might be useful for fuzzing, as we should be able to distinguish signatures which are specific to a jit backends.

Thus replacing backtraces like:

(gdb) bt
#0  0x0000000000f83faa in js::math_cos at js/src/jsmath.cpp:384
#1  0x0000000000ca7974 in js::CallJSNative at js/src/jscntxtinlines.h:235
#2  0x0000000000c854bb in js::Invoke at js/src/vm/Interpreter.cpp:476
#3  0x000000000069a723 in js::jit::DoCallFallback at js/src/jit/BaselineIC.cpp:6113
#4  0x00007ffff7f42395 in  ()

by backtraces like:

(gdb) bt
#0  0x0000000000f83faa in js::math_cos at js/src/jsmath.cpp:384
#1  0x0000000000ca7974 in js::CallJSNative at js/src/jscntxtinlines.h:235
#2  0x0000000000c854bb in js::Invoke at js/src/vm/Interpreter.cpp:476
#3  0x000000000069a723 in js::jit::DoCallFallback at js/src/jit/BaselineIC.cpp:6113
#4  0x00007ffff7f42395 in <<JitFrame_Exit>> ()
#5  0x00007ffff7f43223 in <<JitFrame_BaselineStub>> ()
#6  0x00007ffff7f4523d in <<JitFrame_BaselineJS>> ()
#7  0x00007ffff7f458c4 in <<JitFrame_BaselineStub>> ()
#8  0x00007ffff7f4426a in <<JitFrame_BaselineJS>> ()
#9  0x00007ffff7f39d5f in <<JitFrame_Entry>> ()
#10 0x00000000006a7032 in EnterBaseline at js/src/jit/BaselineJIT.cpp:150
#11 0x00000000006a7845 in js::jit::EnterBaselineAtBranch at js/src/jit/BaselineJIT.cpp:256
This script add a pretty printer for the Executable Allocator and for the
Executable Pool, such that we can see the ranges while printing the
ExecutableAllocator(s).

It also make the ExecutableAllocator an iterable structure, such that we can
iterate over the hash set of executable pool.

This is useful for the next patch, to list all the pages which are handled
by the Jit.  This way, we can interpret the stack of dead processes without
relying on /proc/pid/maps.
Attachment #8737358 - Flags: review?(jdemooij)
This adds a new strategy for finding executable pages, by looking at JIT
information accesible through TLS.

As GDB still has issues at accessing TLS at anytime, let's not make this
strategy the default one for the moment, but only a fallback strategy when
/proc/pid/maps does not exists.

Making this startegy be the fallback strategy implies that the test case
result does not change, but this make it useful for getting the result out
of the core files.
Attachment #8737366 - Flags: review?(ttromey)
Comment on attachment 8737366 [details] [diff] [review]
GDB Scripts: Use the ExecutableAllocator as a fallback solution for finding JIT pages.

Review of attachment 8737366 [details] [diff] [review]:
-----------------------------------------------------------------

Looks good.
Attachment #8737366 - Flags: review?(ttromey) → review+
Comment on attachment 8737358 [details] [diff] [review]
GDB Scripts: Add pretty printers for js::jit::ExecutableAllocator.

Review of attachment 8737358 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/gdb/tests/test-ExecutableAllocator.cpp
@@ +37,5 @@
> +    do { // Keep allocating until we get a second pool.
> +        execAlloc.alloc(32 * 1024, &pool, ION_CODE);
> +    } while (pool == init);
> +
> +    breakpoint();

The test doesn't get past this? Else the ExecutableAllocator destructor will probably complain about pool leaks.
Attachment #8737358 - Flags: review?(jdemooij) → review+
(In reply to Jan de Mooij [:jandem] from comment #4)
> ::: js/src/gdb/tests/test-ExecutableAllocator.cpp
> > +    breakpoint();
> 
> The test doesn't get past this? Else the ExecutableAllocator destructor will
> probably complain about pool leaks.

(rewrite of comment 5)

Indeed, the test case stops at the breakpoint, and the checks are executed inside gdb.  Then the program is killed.  Thus the destructor is never called.
This patch prevent displaying gdb Memory.error exceptions in the middle of
backtraces which have no runtime_, not jitRuntime_.

I noticed that recently as the default thread selected on the core file was
not the main thread, and it had a null runtime_ field.
Attachment #8739005 - Flags: review?(ttromey)
Comment on attachment 8739005 [details] [diff] [review]
GDB Scripts: Prevent gdb Memory.error when dereferencing null pointers.

Review of attachment 8739005 [details] [diff] [review]:
-----------------------------------------------------------------

Thank you for the patch.  Looks good.
Attachment #8739005 - Flags: review?(ttromey) → review+
I added documentation on how to use the gdb unwinder on a core file on the Hacking Tips page.

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Hacking_Tips#Printing_the_JS_stack_%28from_gdb%29
You need to log in before you can comment on or make changes to this bug.