Currently, ASan (and other sanitizers) is built with -fomit-frame-pointer, which doesn't go well in combination with stacktrace snapshots that ASan takes. Basically whenever the snapshot contains a no-fp frame, the caller of such a function is missing from the backtrace. I propose to remove this build settings.
Details
Diff Detail
Event Timeline
Stack traces are not supposed to contain sanitizer functions. Can you give an example of when this causes problems?
Do you have an example where this really leads to an incorrect stack trace?
Sergey and I asked Kostya about this a couple of times and his point
was that -fomit-frame-pointer produces faster calls, but doesn't
worsen the reports, because the functions from ASan runtime library
are always on top of the stack.
I am having this problem with libdispatch functions. ASan has wrappers around functions such as dispatch_async, which do appear on the stack trace when using GCD. Unfortunately, when such a no-fp wrapper appears on the stack, it's not that wrapper frame that's missing (that would be probably fine), but it's the caller of it – i.e. the most important frame.
Also in my specific case it's actually another library that's recording stack traces (Xcode's GCD debugging library) and the issue is the same. The backtrace is taken when a dispatch_async is called, and that trace contains the no-fp wrapper function.
[sorry for delay, I was OOO]
I am strongly against any such change as it may lead to performance drop.
Sadly, we don't have a performance bot yet and we will simply not see a performance drop until it is too late.
For a particular interceptor or a set of interceptors the problem can be solved by adding something like "volatile uptr x = GET_CALLER_PC();"
For a particular interceptor or a set of interceptors the problem can be solved by adding something like "volatile uptr x = GET_CALLER_PC();"
This sounds like a very good idea. GET_CALLER_PC, at least in the current implementation, enables frame pointer in the calling function. There are only a few interceptors that really need it.
Of course, hide it in a macro, e.g.
#define ENABLE_FRAME_POINTERS do {volatile uptr enable_fp = GET_CALLER_PC();"} while (0)
What is the performance impact on tsan?
Does it add any frame pointers to __tsan_read/write/func_entry/exit functions?
If yes, please add explicit -fomit-frame-pointer to tsan runtime.
Patch that enables frame pointer only for the selected GCD functions (block-based ones). In all the other, frame pointer is already enabled implicitly by using GET_STACK_TRACE_THREAD.
In the macro I didn't use GET_CALLER_PC as suggested, because it seems this one doesn't enable the frame pointer. Instead I used GET_CURRENT_FRAME, which does the trick.
I'm fine with this change as long as you move ENABLE_FRAME_POINTERS to the only file that uses it (asan_mac.cc) - not sure it would be generally useful.
This is bikeshedding, but I think "ENABLE_FRAME_POINTER" makes more sense since there's only one per function call.