[PATCH] D58156: [Sanitizer] On Darwin `__sanitizer_print_stack_trace` only prints topmost frame

Julian Lettner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 12 16:28:02 PST 2019


yln created this revision.
Herald added subscribers: llvm-commits, Sanitizers, jdoerfert, kubamracek.
Herald added projects: Sanitizers, LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D58156

Files:
  compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
  compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
  compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
  compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc
  compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc


Index: compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc
===================================================================
--- compiler-rt/test/sanitizer_common/TestCases/symbolize_stack.cc
+++ 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>
Index: compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc
===================================================================
--- compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace.cc
+++ 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>
 
Index: compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
===================================================================
--- compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
+++ compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
@@ -22,7 +22,7 @@
   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;
Index: compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
===================================================================
--- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
+++ compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
@@ -729,10 +729,17 @@
 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];
Index: compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
+++ compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
@@ -49,6 +49,7 @@
 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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58156.186556.patch
Type: text/x-patch
Size: 3491 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190213/d642c996/attachment.bin>


More information about the llvm-commits mailing list