Skip to content

Commit

Permalink
[NFC][Sanitizer] Hard-code fast/slow unwinder at call site
Browse files Browse the repository at this point in the history
Also assert that the caller always gets what it requested.

This purely mechanical change simplifies future refactorings and
eventual removal of BufferedStackTrace::Unwind.

Reviewers: vitalybuka

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

llvm-svn: 355022
  • Loading branch information
yln committed Feb 27, 2019
1 parent 628ab5c commit 46e1b16
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 25 deletions.
9 changes: 6 additions & 3 deletions compiler-rt/lib/asan/asan_stack.h
Expand Up @@ -33,7 +33,7 @@ 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, bp, context, 0, 0, fast);
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
#else
AsanThread *t;
stack->size = 0;
Expand All @@ -43,8 +43,11 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
uptr stack_bottom = t->stack_bottom();
ScopedUnwinding unwind_scope(t);
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom,
fast);
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. */
Expand Down
7 changes: 5 additions & 2 deletions compiler-rt/lib/hwasan/hwasan.cpp
Expand Up @@ -157,8 +157,11 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
SymbolizerScope sym_scope;
return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
}
stack->Unwind(max_s, pc, bp, context, t->stack_top(), t->stack_bottom(),
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,
Expand Down
5 changes: 4 additions & 1 deletion compiler-rt/lib/lsan/lsan.h
Expand Up @@ -55,7 +55,10 @@ void GetStackTrace(__sanitizer::BufferedStackTrace *stack,
stack_bottom = t->stack_begin();
}
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
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);
}
}

Expand Down
9 changes: 6 additions & 3 deletions compiler-rt/lib/msan/msan.cc
Expand Up @@ -227,10 +227,13 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
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, request_fast_unwind);
return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
}
stack->Unwind(max_s, pc, bp, context, t->stack_top(), t->stack_bottom(),
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);
}

void PrintWarning(uptr pc, uptr bp) {
Expand Down
Expand Up @@ -57,6 +57,8 @@ void StackTrace::Print() const {
void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
uptr stack_top, uptr stack_bottom,
bool request_fast_unwind) {
// Ensures all call sites get what they requested.
CHECK_EQ(request_fast_unwind, WillUseFastUnwind(request_fast_unwind));
top_frame_bp = (max_depth > 0) ? bp : 0;
// Avoid doing any work for small max_depth.
if (max_depth == 0) {
Expand Down
Expand Up @@ -103,9 +103,11 @@ void ReportMmapWriteExec(int prot) {
GET_CALLER_PC_BP_SP;
(void)sp;
bool fast = common_flags()->fast_unwind_on_fatal;
if (StackTrace::WillUseFastUnwind(fast))
if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast);
stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
} else
stack->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false);

Printf("%s", d.Warning());
Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName);
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/lib/tsan/rtl/tsan_rtl.cc
Expand Up @@ -331,9 +331,11 @@ static void OnStackUnwind(const SignalContext &sig, const void *,
uptr top = 0;
uptr bottom = 0;
bool fast = common_flags()->fast_unwind_on_fatal;
if (StackTrace::WillUseFastUnwind(fast))
if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(kStackTraceMax, sig.pc, sig.bp, sig.context, top, bottom, fast);
stack->Unwind(kStackTraceMax, sig.pc, sig.bp, nullptr, top, bottom, true);
} else
stack->Unwind(kStackTraceMax, sig.pc, 0, sig.context, 0, 0, false);
}

static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
Expand Down
11 changes: 6 additions & 5 deletions compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
Expand Up @@ -732,14 +732,15 @@ void PrintCurrentStackSlow(uptr pc) {
uptr bp = 0;
uptr top = 0;
uptr bottom = 0;
if (__sanitizer::StackTrace::WillUseFastUnwind(false)) {
bp = GET_CURRENT_FRAME();
__sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
}
BufferedStackTrace *ptrace =
new(internal_alloc(MBlockStackTrace, sizeof(BufferedStackTrace)))
BufferedStackTrace();
ptrace->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, false);
if (__sanitizer::StackTrace::WillUseFastUnwind(false)) {
bp = GET_CURRENT_FRAME();
__sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
ptrace->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
} else
ptrace->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false);
for (uptr i = 0; i < ptrace->size / 2; i++) {
uptr tmp = ptrace->trace_buffer[i];
ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/lib/ubsan/ubsan_diag.cc
Expand Up @@ -30,9 +30,11 @@ 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))
if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
stack->Unwind(max_depth, pc, bp, context, top, bottom, fast);
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) {
Expand Down
11 changes: 6 additions & 5 deletions compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
Expand Up @@ -22,14 +22,15 @@ void __sanitizer_print_stack_trace() {
uptr top = 0;
uptr bottom = 0;
bool request_fast_unwind = common_flags()->fast_unwind_on_fatal;
if (__sanitizer::StackTrace::WillUseFastUnwind(request_fast_unwind))
__sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);

GET_CURRENT_PC_BP_SP;
(void)sp;
BufferedStackTrace stack;
stack.Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom,
request_fast_unwind);
if (__sanitizer::StackTrace::WillUseFastUnwind(request_fast_unwind)) {
__sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
stack.Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
} else {
stack.Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false);
}
stack.Print();
}
} // extern "C"
Expand Down

0 comments on commit 46e1b16

Please sign in to comment.