Index: lib/asan/asan_posix.cc =================================================================== --- lib/asan/asan_posix.cc +++ lib/asan/asan_posix.cc @@ -46,11 +46,14 @@ // We also check si_code to filter out SEGV caused by something else other // then hitting the guard page or unmapped memory, like, for example, // unaligned memory access. + CHECK_EQ(false, in_sigsegv_handler); + in_sigsegv_handler = true; if (addr + 128 > sp && addr < sp + 0xFFFF && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR)) ReportStackOverflow(pc, sp, bp, context, addr); else ReportSIGSEGV("SEGV", pc, sp, bp, context, addr); + in_sigsegv_handler = false; } // ---------------------- TSD ---------------- {{{1 Index: lib/sanitizer_common/sanitizer_internal_defs.h =================================================================== --- lib/sanitizer_common/sanitizer_internal_defs.h +++ lib/sanitizer_common/sanitizer_internal_defs.h @@ -210,6 +210,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void NORETURN CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2); + +extern bool in_sigsegv_handler; } // namespace __sanitizer // Check macro Index: lib/sanitizer_common/sanitizer_stacktrace.h =================================================================== --- lib/sanitizer_common/sanitizer_stacktrace.h +++ lib/sanitizer_common/sanitizer_stacktrace.h @@ -15,6 +15,10 @@ #include "sanitizer_internal_defs.h" +#if SANITIZER_FREEBSD +#include // for __FreeBSD_version +#endif + namespace __sanitizer { static const uptr kStackTraceMax = 256; @@ -29,6 +33,13 @@ # define SANITIZER_CAN_FAST_UNWIND 1 #endif +// Fast unwind is the only option on Mac. +#if SANITIZER_MAC +# define SANITIZER_CAN_SLOW_UNWIND 0 +#else +# define SANITIZER_CAN_SLOW_UNWIND 1 +#endif + struct StackTrace { const uptr *trace; uptr size; @@ -40,13 +51,14 @@ void Print() const; static bool WillUseFastUnwind(bool request_fast_unwind) { - // Check if fast unwind is available. Fast unwind is the only option on Mac. - // It is also the only option on FreeBSD as the slow unwinding that - // leverages _Unwind_Backtrace() yields the call stack of the signal's - // handler and not of the code that raised the signal (as it does on Linux). if (!SANITIZER_CAN_FAST_UNWIND) return false; - else if (SANITIZER_MAC != 0 || SANITIZER_FREEBSD != 0) + else if (!SANITIZER_CAN_SLOW_UNWIND) + return true; + else if (SANITIZER_FREEBSD && in_sigsegv_handler) + // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace() + // yields the call stack of the signal's handler and not of the code + // that raised the signal (as it does on Linux). return true; return request_fast_unwind; } Index: lib/sanitizer_common/sanitizer_stacktrace.cc =================================================================== --- lib/sanitizer_common/sanitizer_stacktrace.cc +++ lib/sanitizer_common/sanitizer_stacktrace.cc @@ -17,6 +17,8 @@ namespace __sanitizer { +bool in_sigsegv_handler = false; + uptr StackTrace::GetPreviousInstructionPc(uptr pc) { #if defined(__arm__) // Cancel Thumb bit.