summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Lettner <jlettner@apple.com>2019-02-18 18:47:49 +0000
committerJulian Lettner <jlettner@apple.com>2019-02-18 18:47:49 +0000
commiteb3bcc1c951039c7ab4656ef44e7e5deffe1ad92 (patch)
treef8bf5e754663ae4b5a5011c9e314d05fe5b9c109
parentdebaf4bd31a18265768aaf6485a87db7410ef1b7 (diff)
downloadbcm5719-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
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc9
-rw-r--r--compiler-rt/lib/ubsan/ubsan_diag_standalone.cc2
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc4
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc4
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>
OpenPOWER on IntegriCloud