diff options
author | Alexey Samsonov <samsonov@google.com> | 2014-03-04 13:12:25 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2014-03-04 13:12:25 +0000 |
commit | 1f5d9ca9ff46ab51b1f0567f1722fed810af0e6c (patch) | |
tree | 5154a3a9d80667dbc3e840be25192db30e3bfc90 /lib | |
parent | cf0d108fb5eabb382662c583787c609adbf3ac0f (diff) |
[ASan] Speed up stack trace unwinding for stacks of size 2.
Summary:
We don't need to do any work in this case - just take
the current PC and caller PC.
Reviewers: eugenis, ygribov
Reviewed By: eugenis
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D2936
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@202845 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asan/asan_allocator2.cc | 1 | ||||
-rw-r--r-- | lib/asan/asan_linux.cc | 1 | ||||
-rw-r--r-- | lib/asan/asan_stack.h | 70 | ||||
-rw-r--r-- | lib/asan/asan_thread.h | 1 |
4 files changed, 45 insertions, 28 deletions
diff --git a/lib/asan/asan_allocator2.cc b/lib/asan/asan_allocator2.cc index 773d33bd3..a759b8e35 100644 --- a/lib/asan/asan_allocator2.cc +++ b/lib/asan/asan_allocator2.cc @@ -19,6 +19,7 @@ #include "asan_mapping.h" #include "asan_poisoning.h" #include "asan_report.h" +#include "asan_stack.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_flags.h" diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index 4e7ca7e77..f2aa690ad 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -18,6 +18,7 @@ #include "asan_interceptors.h" #include "asan_internal.h" #include "asan_thread.h" +#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h index f7abb9335..3cbd2dad4 100644 --- a/lib/asan/asan_stack.h +++ b/lib/asan/asan_stack.h @@ -19,48 +19,64 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_stacktrace.h" +namespace __asan { + // Get the stack trace with the given pc and bp. // The pc will be in the position 0 of the resulting stack trace. // The bp may refer to the current frame or to the caller's frame. +ALWAYS_INLINE +void GetStackTraceWithPcBpAndContext(StackTrace *stack, uptr max_depth, uptr pc, + uptr bp, void *context, bool fast) { #if SANITIZER_WINDOWS -#define GET_STACK_TRACE_WITH_PC_BP_AND_CONTEXT(max_s, pc, bp, context, fast) \ - StackTrace stack; \ - stack.Unwind(max_s, pc, bp, context, 0, 0, fast) + stack->Unwind(max_depth, pc, bp, context, 0, 0, fast); #else -#define GET_STACK_TRACE_WITH_PC_BP_AND_CONTEXT(max_s, pc, bp, context, fast) \ - StackTrace stack; \ - { \ - AsanThread *t; \ - stack.size = 0; \ - if (asan_inited) { \ - if ((t = GetCurrentThread()) && !t->isUnwinding()) { \ - uptr stack_top = t->stack_top(); \ - uptr stack_bottom = t->stack_bottom(); \ - ScopedUnwinding unwind_scope(t); \ - stack.Unwind(max_s, pc, bp, context, stack_top, stack_bottom, fast); \ - } else if (t == 0 && !fast) { \ - /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ \ - stack.Unwind(max_s, pc, bp, context, 0, 0, false); \ - } \ - } \ + AsanThread *t; + stack->size = 0; + if (asan_inited) { + if ((t = GetCurrentThread()) && !t->isUnwinding()) { + uptr stack_top = t->stack_top(); + uptr stack_bottom = t->stack_bottom(); + ScopedUnwinding unwind_scope(t); + stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast); + } else if (t == 0 && !fast) { + /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ + stack->Unwind(max_depth, pc, bp, context, 0, 0, false); + } } #endif // SANITIZER_WINDOWS +} + +} // namespace __asan // NOTE: A Rule of thumb is to retrieve stack trace in the interceptors // as early as possible (in functions exposed to the user), as we generally // don't want stack trace to contain functions from ASan internals. #define GET_STACK_TRACE(max_size, fast) \ - GET_STACK_TRACE_WITH_PC_BP_AND_CONTEXT(max_size, StackTrace::GetCurrentPc(), \ - GET_CURRENT_FRAME(), 0, fast) + StackTrace stack; \ + if (max_size <= 2) { \ + stack.size = max_size; \ + if (max_size > 0) { \ + stack.top_frame_bp = GET_CURRENT_FRAME(); \ + stack.trace[0] = StackTrace::GetCurrentPc(); \ + } \ + if (max_size > 1) \ + stack.trace[1] = GET_CALLER_PC(); \ + } else { \ + GetStackTraceWithPcBpAndContext(&stack, max_size, \ + StackTrace::GetCurrentPc(), \ + GET_CURRENT_FRAME(), 0, fast); \ + } -#define GET_STACK_TRACE_FATAL(pc, bp) \ - GET_STACK_TRACE_WITH_PC_BP_AND_CONTEXT(kStackTraceMax, pc, bp, 0, \ - common_flags()->fast_unwind_on_fatal) +#define GET_STACK_TRACE_FATAL(pc, bp) \ + StackTrace stack; \ + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, 0, \ + common_flags()->fast_unwind_on_fatal) -#define GET_STACK_TRACE_SIGNAL(pc, bp, context) \ - GET_STACK_TRACE_WITH_PC_BP_AND_CONTEXT(kStackTraceMax, pc, bp, context, \ - common_flags()->fast_unwind_on_fatal) +#define GET_STACK_TRACE_SIGNAL(pc, bp, context) \ + StackTrace stack; \ + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, \ + common_flags()->fast_unwind_on_fatal) #define GET_STACK_TRACE_FATAL_HERE \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h index 6bcb01ba3..1bce25c28 100644 --- a/lib/asan/asan_thread.h +++ b/lib/asan/asan_thread.h @@ -17,7 +17,6 @@ #include "asan_allocator.h" #include "asan_internal.h" #include "asan_fake_stack.h" -#include "asan_stack.h" #include "asan_stats.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" |