TraceStackFramePointers should check stack |
|||
Issue descriptionTraceStackFramePointers relies on heuristics to check whether stack frame pointer is inside the stack (i.e. safe to read). For Android we had to implement precise checks because heuristics are not enough in some cases (see crbug.com/602701#c18 ). We should try do something similar on Linux. Things I've already tried (see crrev.com/1975393002): 1. Use pthread_getattr_np() to get stack attributes. Issues: * Sometimes fails for the main thread because sandbox prevents reading proc/maps. * Calls sched_getaffinity, which is blocked by the sandbox. * Allocates memory, which causes it to reenter itself and deadlock (only seen on main thread). All those issues can be worked around: * Use __libc_stack_end for the main thread to avoid errors and the deadlocks. * Punch a hole in the sandbox to allow sched_getaffinity for profiling builds. This works, but is fragile - any thread that calls pthread_getattr_np() before doing any allocation will deadlock. 2. Use mincore() to detect unmapped pages. Issues: * Requires hole in a sandbox, since by default mincore syscall is banned. * Stacks for threads go one after another without unmapped pages in between: 7f4299c1f000-7f429a41f000 rw-p 00000000 00:00 0 [stack:109410] 7f429a41f000-7f429a420000 ---p 00000000 00:00 0 7f429a420000-7f429ac20000 rw-p 00000000 00:00 0 [stack:109287] 7f429ac20000-7f429ac21000 ---p 00000000 00:00 0 7f429ac21000-7f429b421000 rw-p 00000000 00:00 0 [stack:109286] So not only can't we reliably determine where stack ends, but we can also give unaccessible guard page in between (---p) a pass, and crash later trying to read it.
,
Aug 10 2016
Idea: we don't need strict stack end for the purpose of reliable stack unwinding, it's enough to know some address at which we should stop. So we could interpose pthread_create, provide our own thread function, get stack address there, put it in pthread specific, and call user provided thread function. TraceStackFramePointers() would then retrieve the address from the pthread specific. We already have a solution for the main thread on Linux (__libc_stack_end), and this trick might solve remaining non main thread cases.
,
Aug 30 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/2ff54586e0102659c1034d58269ac376d1aacc20 commit 2ff54586e0102659c1034d58269ac376d1aacc20 Author: dskiba <dskiba@google.com> Date: Tue Aug 30 03:57:43 2016 Check stack pointer to be inside the stack when unwinding on Linux. On Linux unwinding stack using frame pointers relies on heuristics, which sometimes fail to catch invalid stack pointers. However it's hard to get stack boundaries for all threads on Linux, see the bug. This CL checks stack pointers against real stack boundary for the main thread only, which is enough to fix recently discovered crash ( crbug.com/617730#c1 ). BUG= 617730 Review-Url: https://codereview.chromium.org/2203053003 Cr-Commit-Position: refs/heads/master@{#415065} [modify] https://crrev.com/2ff54586e0102659c1034d58269ac376d1aacc20/base/debug/stack_trace.cc
,
Nov 28 2016
,
May 16 2018
We now switched to memlog, which can do sampling. With sampling it does a lot less stack unwinding, so actually just using standard drwarf unwinding is fine. |
|||
►
Sign in to add a comment |
|||
Comment 1 by dskiba@chromium.org
, Aug 2 2016