Hi,
We have multiple ways of getting stack traces, and it is hard to keep track
of
them all. I wrote down some notes that reflect my understanding, and I
thought
I'd share it in case it's useful, and in case people have ideas on how to
improve things.
Nick
-----------------------------------------------------------------------------
mozglue/misc/StackWalk.{h,cpp}
-----------------------------------------------------------------------------
The main stackwalk function is MozStackWalk:
> MFBT_API bool
> MozStackWalk(MozWalkStackCallback aCallback,
> uint32_t aSkipFrames,
> uint32_t aMaxFrames,
> void* aClosure,
Here's how it is implemented on different platforms.
- Win32 Custom code using StackWalk64()
- Win64 Custom code using RtlVirtualUnwind()
- Linux32 FramePointerStackWalk?[1]
- Linux64 _Unwind_Backtrace
- Mac32? FramePointerStackWalk?[1]
- Mac64 _Unwind_Backtrace[2]
- Android _Unwind_Backtrace?
- Other (unimplemented, mostly)
[1] FramePointerStackWalk() is a straightforward FP-chasing unwind. It is a
public function and so can be called directly, too.
[2] _Unwind_Backtrace is really slow on some recent Mac versions, alas.
On Windows there is also MozStackWalkThread(), which differs from
MozStackWalk() by being able to walk the stack of a different thread.
-----------------------------------------------------------------------------
Gecko Profiler
-----------------------------------------------------------------------------
The Gecko Profiler has a couple of other stack walkers used on some
platforms.
- LUL: Linux-only stack walker that uses DWARF info to unwind.
- EHABI: Android-only stack walker that uses the ARM exception handling ABI.
-----------------------------------------------------------------------------
Places where stack walking is used.
-----------------------------------------------------------------------------
Lots of places use MozStackWalk() for all platforms: telemetry,
ah_crap_handler, HangMonitor, BlockingResourceBase,
TlsAllocationTracker.cpp,
nsTraceRefCnt.cpp, etc. These are all places where the number of stack walks
performed is small, so speed isn't that important.
The Gecko Profiler and DMD use a mixture of stack walkers, as per this
table.
Gecko Profiler DMD
-------------- ---
Win32 FramePointerStackWalk FramePointerStackWalk
Win64 MozStackWalk MozStackWalk
Linux32 LUL MozStackWalk
Linux64 LUL MozStackWalk
Mac32? FramePointerStackWalk[1] FramePointerStackWalk[1]
Mac64 FramePointerStackWalk[1] FramePointerStackWalk[1]
Android EHABI MozStackWalk
[1] requires MOZ_PROFILING to be set so that frame pointers are used.
The Gecko Profiler and DMD do *lots* of stack walks, so speed is important
for
them.
Note that the Gecko Profiler needs to stackwalk other threads than the
current
one.
- Windows' MozStackWalkThread() allows that by naming the thread.
- FramePointerStackWalk() allows that, because you just give it the
to-be-walked thread's registers.
- _Unwind_Backtrace() doesn't allow it.
HangMonitor also requires off-thread stackwalking, but it's Windows-only
(perhaps exactly because it requires off-thread stackwalking). It could
potentially use profiler_suspend_and_sample() instead (see next paragraph).
Finally, the Gecko Profiler also has a public function
profiler_suspend_and_sample_thread() that walks the stack of another thread
(using the abovementioned stackwalkers), and interleaves that with
pseudostacks
and JS stacks. BHR uses this function.
_______________________________________________
dev-platform mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-platform