Skip to content

Commit

Permalink
[NFC][Sanitizer] Pull up GetStackTrace into sanitizer_common
Browse files Browse the repository at this point in the history
We already independently declare GetStackTrace in all (except TSan)
sanitizer runtime headers. Lets move it to sanitizer_stacktrace.h to
have one canonical way to fill in a BufferedStackFrame. Also enables us
to use it in sanitizer_common itself.

This patch defines GetStackTrace for TSan and moves the function from
ubsan_diag.cc to ubsan_diag_standalone.cc to avoid duplicate symbols
for the UBSan-ASan runtime.

Other than that this patch just moves the code out of headers and into
the correct namespace.

Reviewers: vitalybuka

Differential Revision: https://reviews.llvm.org/D58651

llvm-svn: 355039
  • Loading branch information
yln committed Feb 27, 2019
1 parent 6a19836 commit a0884da
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 108 deletions.
28 changes: 28 additions & 0 deletions compiler-rt/lib/asan/asan_stack.cc
Expand Up @@ -28,6 +28,34 @@ u32 GetMallocContextSize() {

} // namespace __asan

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
uptr pc, uptr bp, void *context, bool fast) {
using namespace __asan;
#if SANITIZER_WINDOWS
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
#else
AsanThread *t;
stack->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(fast))
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom,
true);
else
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
}
} else if (!t && !fast) {
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
}
}
#endif // SANITIZER_WINDOWS
}

// ------------------ Interface -------------- {{{1

extern "C" {
Expand Down
31 changes: 0 additions & 31 deletions compiler-rt/lib/asan/asan_stack.h
Expand Up @@ -26,37 +26,6 @@ static const u32 kDefaultMallocContextSize = 30;
void SetMallocContextSize(u32 size);
u32 GetMallocContextSize();

// 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 GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
void *context, bool fast) {
#if SANITIZER_WINDOWS
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
#else
AsanThread *t;
stack->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(fast))
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom,
true);
else
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
}
} else if (!t && !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
Expand Down
42 changes: 22 additions & 20 deletions compiler-rt/lib/hwasan/hwasan.cpp
Expand Up @@ -144,26 +144,6 @@ static void InitializeFlags() {
if (common_flags()->help) parser.PrintFlagDescriptions();
}

void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
void *context, bool request_fast_unwind) {
Thread *t = GetCurrentThread();
if (!t) {
// the thread is still being created.
stack->size = 0;
return;
}
if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
}
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
true);
else
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
}

static void HWAsanCheckFailed(const char *file, int line, const char *cond,
u64 v1, u64 v2) {
Report("HWAddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
Expand Down Expand Up @@ -264,6 +244,28 @@ void InitInstrumentation() {

} // namespace __hwasan

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
uptr bp, void *context,
bool request_fast_unwind) {
using namespace __hwasan;
Thread *t = GetCurrentThread();
if (!t) {
// the thread is still being created.
stack->size = 0;
return;
}
if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
}
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
true);
else
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
}

// Interface.

using namespace __hwasan;
Expand Down
3 changes: 0 additions & 3 deletions compiler-rt/lib/hwasan/hwasan.h
Expand Up @@ -104,9 +104,6 @@ struct SymbolizerScope {
~SymbolizerScope() { ExitSymbolizer(); }
};

void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
void *context, bool request_fast_unwind);

// Returns a "chained" origin id, pointing to the given stack trace followed by
// the previous origin id.
u32 ChainOrigin(u32 id, StackTrace *stack);
Expand Down
18 changes: 18 additions & 0 deletions compiler-rt/lib/lsan/lsan.cc
Expand Up @@ -32,6 +32,24 @@ bool WordIsPoisoned(uptr addr) {

} // namespace __lsan

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
uptr pc, uptr bp, void *context, bool fast) {
using namespace __lsan;
uptr stack_top = 0, stack_bottom = 0;
ThreadContext *t;
if (StackTrace::WillUseFastUnwind(fast) &&
(t = CurrentThreadContext())) {
stack_top = t->stack_end();
stack_bottom = t->stack_begin();
}
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
if (StackTrace::WillUseFastUnwind(fast))
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
else
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
}
}

using namespace __lsan; // NOLINT

static void InitializeFlags() {
Expand Down
22 changes: 0 additions & 22 deletions compiler-rt/lib/lsan/lsan.h
Expand Up @@ -40,28 +40,6 @@ void ReplaceSystemMalloc();
__lsan_init(); \
} while (0)

// 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 GetStackTrace(__sanitizer::BufferedStackTrace *stack,
__sanitizer::uptr max_depth, __sanitizer::uptr pc,
__sanitizer::uptr bp, void *context, bool fast) {
uptr stack_top = 0, stack_bottom = 0;
ThreadContext *t;
if (__sanitizer::StackTrace::WillUseFastUnwind(fast) &&
(t = CurrentThreadContext())) {
stack_top = t->stack_end();
stack_bottom = t->stack_begin();
}
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
if (StackTrace::WillUseFastUnwind(fast))
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
else
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
}
}

} // namespace __lsan

extern bool lsan_inited;
Expand Down
32 changes: 17 additions & 15 deletions compiler-rt/lib/msan/msan.cc
Expand Up @@ -221,21 +221,6 @@ static void InitializeFlags() {
if (f->store_context_size < 1) f->store_context_size = 1;
}

void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
void *context, bool request_fast_unwind) {
MsanThread *t = GetCurrentThread();
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
}
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
true);
else
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
}

void PrintWarning(uptr pc, uptr bp) {
PrintWarningWithOrigin(pc, bp, __msan_origin_tls);
}
Expand Down Expand Up @@ -316,6 +301,23 @@ u32 ChainOrigin(u32 id, StackTrace *stack) {

} // namespace __msan

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
uptr bp, void *context,
bool request_fast_unwind) {
using namespace __msan;
MsanThread *t = GetCurrentThread();
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
}
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
true);
else
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
}

// Interface.

using namespace __msan;
Expand Down
3 changes: 0 additions & 3 deletions compiler-rt/lib/msan/msan.h
Expand Up @@ -312,9 +312,6 @@ struct SymbolizerScope {
void PrintWarning(uptr pc, uptr bp);
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);

void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
void *context, bool request_fast_unwind);

// Unpoison first n function arguments.
void UnpoisonParam(uptr n);
void UnpoisonThreadLocalState();
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
Expand Up @@ -121,6 +121,12 @@ static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {
return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);
}

// 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.
void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
void *context, bool request_fast_unwind);

} // namespace __sanitizer

// Use this macro if you want to print stack trace with the caller
Expand Down
12 changes: 12 additions & 0 deletions compiler-rt/lib/tsan/rtl/tsan_stack_trace.cc
Expand Up @@ -48,3 +48,15 @@ void VarSizeStackTrace::ReverseOrder() {
}

} // namespace __tsan

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
uptr pc, uptr bp, void *context,
bool request_fast_unwind) {
uptr top = 0;
uptr bottom = 0;
if (StackTrace::WillUseFastUnwind(request_fast_unwind)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
} else
stack->Unwind(kStackTraceMax, pc, 0, context, 0, 0, false);
}
11 changes: 0 additions & 11 deletions compiler-rt/lib/ubsan/ubsan_diag.cc
Expand Up @@ -26,17 +26,6 @@

using namespace __ubsan;

void __ubsan::GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc,
uptr bp, void *context, bool fast) {
uptr top = 0;
uptr bottom = 0;
if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
} else
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
}

static void MaybePrintStackTrace(uptr pc, uptr bp) {
// We assume that flags are already parsed, as UBSan runtime
// will definitely be called when we print the first diagnostics message.
Expand Down
3 changes: 0 additions & 3 deletions compiler-rt/lib/ubsan/ubsan_diag.h
Expand Up @@ -234,9 +234,6 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET);
GET_CALLER_PC_BP; \
ReportOptions Opts = {unrecoverable_handler, pc, bp}

void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
void *context, bool fast);

/// \brief Instantiate this class before printing diagnostics in the error
/// report. This class ensures that reports from different threads and from
/// different sanitizers won't be mixed.
Expand Down
11 changes: 11 additions & 0 deletions compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
Expand Up @@ -14,6 +14,17 @@
#if CAN_SANITIZE_UB
#include "ubsan_diag.h"

void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
uptr pc, uptr bp, void *context, bool fast) {
uptr top = 0;
uptr bottom = 0;
if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
} else
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
}

using namespace __ubsan;

extern "C" {
Expand Down

0 comments on commit a0884da

Please sign in to comment.