diff options
author | Julian Lettner <jlettner@apple.com> | 2019-02-18 18:47:49 +0000 |
---|---|---|
committer | Julian Lettner <jlettner@apple.com> | 2019-02-18 18:47:49 +0000 |
commit | eb3bcc1c951039c7ab4656ef44e7e5deffe1ad92 (patch) | |
tree | f8bf5e754663ae4b5a5011c9e314d05fe5b9c109 | |
parent | debaf4bd31a18265768aaf6485a87db7410ef1b7 (diff) | |
download | bcm5719-llvm-eb3bcc1c951039c7ab4656ef44e7e5deffe1ad92.tar.gz bcm5719-llvm-eb3bcc1c951039c7ab4656ef44e7e5deffe1ad92.zip |
[Sanitizer] On Darwin `__sanitizer_print_stack_trace` only prints topmost frame
In compiler-rt we have the notion of a `fast` and a `slow` stack
unwinder. Darwin currently only supports the fast unwinder.
From reading the code, my understanding is that
`BufferedStackTrace::Unwind` can be called with `bp=0, stack_top=0,
stack_bottom=0, request_fast_unwind=false`. If
`request_fast_unwind=true`, then we alos need to supply bp, stack_top,
and stack_bottom.
However, `BufferedStackTrace::Unwind` uses
`StackTrace::WillUseFastUnwind` which will adapt `request_fast_unwind`
if the requested unwinder is not supported. On Darwin, the result is
that we don't pass actual values for bp, stack_top, and stack_bottom,
but end up using the fast unwinder. The tests then fail because we only
print the topmost stack frame.
This patch adds a check to `WillUseFastUnwind` at the point of usage to
avoid the mismatch between `request_fast_unwind` and what `Unwind`
actually does. I am also interested in cleaning up the
`request_fast_unwind` machinery so this patch just the simplest thing
possible so I can enable the tests.
Reviewers: vitalybuka, vsk
Differential Revision: https://reviews.llvm.org/D58156
llvm-svn: 354282
5 files changed, 14 insertions, 6 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc index c3d9f9a42c7..c49a7e99856 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc @@ -49,6 +49,7 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) { static inline uhwptr *GetCanonicFrame(uptr bp, uptr stack_top, uptr stack_bottom) { + CHECK_GT(stack_top, stack_bottom); #ifdef __arm__ if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0; uhwptr *bp_prev = (uhwptr *)bp; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc index 0a1f2284bfb..14ecdfb7223 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc @@ -729,10 +729,17 @@ void PrintCurrentStack(ThreadState *thr, uptr pc) { ALWAYS_INLINE void PrintCurrentStackSlow(uptr pc) { #if !SANITIZER_GO + 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, 0, 0, 0, 0, false); + ptrace->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, 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]; diff --git a/compiler-rt/lib/ubsan/ubsan_diag_standalone.cc b/compiler-rt/lib/ubsan/ubsan_diag_standalone.cc index 11340cf049e..863d51977f1 100644 --- a/compiler-rt/lib/ubsan/ubsan_diag_standalone.cc +++ b/compiler-rt/lib/ubsan/ubsan_diag_standalone.cc @@ -22,7 +22,7 @@ void __sanitizer_print_stack_trace() { uptr top = 0; uptr bottom = 0; bool request_fast_unwind = common_flags()->fast_unwind_on_fatal; - if (request_fast_unwind) + if (__sanitizer::StackTrace::WillUseFastUnwind(request_fast_unwind)) __sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom); GET_CURRENT_PC_BP_SP; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc index 82fc8a845ae..d74f9c9a153 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc +++ b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc @@ -1,8 +1,8 @@ // RUN: %clangxx -O0 %s -o %t && %env_tool_opts=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s // RUN: %env_tool_opts=stack_trace_format='"frame:%n lineno:%l"' %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM -// FIXME(dliew): Make this test work with other sanitizers -// XFAIL: darwin && (lsan || tsan || ubsan) +// FIXME(dliew): Make this test work on Darwin with LSan +// XFAIL: darwin && lsan #include <sanitizer/common_interface_defs.h> diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc b/compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc index 0a2786931af..a8fadae4173 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc @@ -2,8 +2,8 @@ // Test that symbolizer does not crash on frame with large function name. -// FIXME(dliew): Make this test work with the other sanitizers. -// XFAIL: darwin && (lsan || tsan || ubsan) +// FIXME(dliew): Make this test work on Darwin with LSan +// XFAIL: darwin && lsan #include <sanitizer/common_interface_defs.h> #include <vector> |