From 4ce918e3942f0333ccb7d65d6265f4fc5f5324be Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Tue, 5 Mar 2019 00:41:15 +0000 Subject: [PATCH] [NFC][Sanitizer] Cleanup ASan's GetStackTrace implementation Cleanup ASan's __sanitizer::BufferedStackTrace::UnwindImpl (formerly GetStackTrace) implementation. Start with ASan because it is the most complex implementation. GetStackTrace implementations seem to have started out as exact copies of the original implementation in ASan, but have diverged in subtle ways. My goal is to parameterize this algorithm (via templating or callbacks) so we can share the implementation and get rid of the inversed dependency (sanitizer_common depends on concrete implementations in asan, ubsan, etc.). This should also help us to avoid those pesky linker errors caused by undefined, duplicate, and weak symbols on Windows. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D58861 llvm-svn: 355355 --- compiler-rt/lib/asan/asan_stack.cc | 33 ++++++++----------- .../sanitizer_common/sanitizer_stacktrace.h | 5 +++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/compiler-rt/lib/asan/asan_stack.cc b/compiler-rt/lib/asan/asan_stack.cc index 72caf1f8bc81..0bcba419da8b 100644 --- a/compiler-rt/lib/asan/asan_stack.cc +++ b/compiler-rt/lib/asan/asan_stack.cc @@ -31,28 +31,23 @@ u32 GetMallocContextSize() { void __sanitizer::BufferedStackTrace::UnwindImpl( uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { using namespace __asan; -#if SANITIZER_WINDOWS - Unwind(max_depth, pc, 0, context, 0, 0, false); -#else - AsanThread *t; size = 0; - if (LIKELY(asan_inited)) { - if ((t = GetCurrentThread()) && !t->isUnwinding()) { - uptr stack_top = t->stack_top(); - uptr stack_bottom = t->stack_bottom(); - ScopedUnwinding unwind_scope(t); - if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { - if (StackTrace::WillUseFastUnwind(request_fast)) - Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true); - else - Unwind(max_depth, pc, 0, context, 0, 0, false); - } - } else if (!t && !request_fast) { - /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ - Unwind(max_depth, pc, bp, context, 0, 0, false); + if (UNLIKELY(!asan_inited)) return; + + AsanThread *t = GetCurrentThread(); + if (t && !t->isUnwinding() && WillUseFastUnwind(request_fast)) { + uptr top = t->stack_top(); + uptr bottom = t->stack_bottom(); + ScopedUnwinding unwind_scope(t); + if (!SANITIZER_MIPS || IsValidFrame(bp, top, bottom)) { + UnwindFast(pc, bp, top, bottom, max_depth); + return; } } -#endif // SANITIZER_WINDOWS + +#if SANITIZER_CAN_SLOW_UNWIND + UnwindSlowWithOptionalContext(pc, context, max_depth); +#endif } // ------------------ Interface -------------- {{{1 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h index 4d19979f2c5a..ec63b66cfec2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h @@ -134,6 +134,11 @@ struct BufferedStackTrace : public StackTrace { void UnwindSlow(uptr pc, u32 max_depth); void UnwindSlow(uptr pc, void *context, u32 max_depth); + void UnwindSlowWithOptionalContext(uptr pc, void *context, u32 max_depth) { + if (context) UnwindSlow(pc, context, max_depth); + else UnwindSlow(pc, max_depth); + } + void PopStackFrames(uptr count); uptr LocatePcInTrace(uptr pc);