Open
Bug 968531
Opened 12 years ago
Updated 3 years ago
Make NS_StackWalk work on ARM Linux
Categories
(Core :: XPCOM, defect)
Tracking
()
NEW
People
(Reporter: jld, Assigned: jld)
References
Details
Currently we don't have an NS_StackWalk implementation that works on ARM Linux, and this can be a problem when investigating certain kinds of bug (e.g., on B2G). The existing option in nsStackWalk.cpp to use _Unwind_Backtrace might work if it were enabled(?), but we should make sure that the not-quite-sorted .ARM.exidx section seen in the B2G ICS libc.so (caused by a linker bug that probably also affects some versions of regular Android) doesn't cause problems.
Alternately, there's an ARM EH unwinder in tools/profiler (bug 810526) that could be moved into xpcom/base with a replacement for (or along with) the code in that directory that enumerates loaded libraries. The core unwinder is async-signal-safe and relatively fast, but there's a setup step that has to be called first to locate (and, to work around the previously mentioned linker bug, sort) the exception indices of loaded objects.
| Assignee | ||
Comment 1•11 years ago
|
||
So this works:
static void __attribute__((naked))
CallStackWalk(NS_WalkStackCallback callback, const unsigned long *regs)
{
asm("push {r7, lr}\n\t"
"mov r7, r1\n\t"
".save {r0 - r15}\n\t"
".setfp r7, sp, #0\n\t"
"movs r1, #1\n\t"
"movs r2, #0\n\t"
"movs r3, #0\n\t"
"push {r2, r3}\n\t"
"bl NS_StackWalk\n\t"
"pop {r2, r3, r7, pc}");
}
If you call NS_StackWalk in a signal handler, it will call _Unwind_Backtrace, which will dutifully unwind your signal handler... and then hit the signal trampoline and stop. Which, if you're trying to get the stack of the code that caused the signal to be raised, is not helpful.
But _Unwind_Backtrace is an interpreter for a well-specified language, and we control the program it's running. Thus, when the unwinder reaches this function, it will set the virtual stack pointer to our chosen value (kept in the callee-saved R7), as if it were a frame pointer, and then it will pop all 16 core registers — i.e., overwrite the simulated machine's register file with whatever we want.
A better variation of this approach would be to pass the ucontext_t* into NS_StackWalk and have it set up the call to _Unwind_Backtrace this way. This could be a more general feature to use the provided context instead of applying the aSkipFrames argument to the current context, if implemented for the unwinder and platform in question.
Assignee: nobody → jld
Updated•3 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•