summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-11-07 07:28:33 +0000
committerAlexey Samsonov <samsonov@google.com>2013-11-07 07:28:33 +0000
commitf16dc4234098a22a9d0d56f0198d87905481e7fd (patch)
tree53e01f2d80633dcbe113757592e928c9cee682c0
parentcca3cc0fc367d221b41135b13cdbca810639b0cd (diff)
downloadcompiler-rt-f16dc4234098a22a9d0d56f0198d87905481e7fd.tar.gz
compiler-rt-f16dc4234098a22a9d0d56f0198d87905481e7fd.tar.bz2
compiler-rt-f16dc4234098a22a9d0d56f0198d87905481e7fd.tar.xz
[Sanitizer] Make StackTrace::Unwind the only public way to unwind a stack trace.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@194196 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/msan.cc9
-rw-r--r--lib/msan/msan.h2
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.h21
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc10
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc23
-rw-r--r--lib/tsan/rtl/tsan_rtl_report.cc4
6 files changed, 39 insertions, 30 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index 2530fb11..26498a9b 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -180,16 +180,15 @@ static void GetCurrentStackBounds(uptr *stack_top, uptr *stack_bottom) {
}
void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
- bool fast) {
- if (!fast) {
+ bool request_fast_unwind) {
+ if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
- return stack->SlowUnwindStack(pc, max_s);
+ return stack->Unwind(max_s, pc, bp, 0, 0, request_fast_unwind);
}
-
uptr stack_top, stack_bottom;
GetCurrentStackBounds(&stack_top, &stack_bottom);
- stack->FastUnwindStack(pc, bp, stack_top, stack_bottom, max_s);
+ stack->Unwind(max_s, pc, bp, stack_top, stack_bottom, request_fast_unwind);
}
void PrintWarning(uptr pc, uptr bp) {
diff --git a/lib/msan/msan.h b/lib/msan/msan.h
index 51fa2ebb..4e6c6194 100644
--- a/lib/msan/msan.h
+++ b/lib/msan/msan.h
@@ -72,7 +72,7 @@ void PrintWarning(uptr pc, uptr bp);
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
- bool fast);
+ bool request_fast_unwind);
void ReportUMR(StackTrace *stack, u32 origin);
void ReportExpectedUMRNotFound(StackTrace *stack);
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.h b/lib/sanitizer_common/sanitizer_stacktrace.h
index b03f5791..035f39f8 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -47,17 +47,26 @@ struct StackTrace {
trace[i] = src[i];
}
+ static bool WillUseFastUnwind(bool request_fast_unwind) {
+ // Check if fast unwind is available. Fast unwind is the only option on Mac.
+ if (!SANITIZER_CAN_FAST_UNWIND)
+ return false;
+ else if (SANITIZER_MAC)
+ return true;
+ return request_fast_unwind;
+ }
+
void Unwind(uptr max_depth, uptr pc, uptr bp, uptr stack_top,
- uptr stack_bottom, bool fast);
- // FIXME: Make FastUnwindStack and SlowUnwindStack private methods.
+ uptr stack_bottom, bool request_fast_unwind);
+
+ static uptr GetCurrentPc();
+ static uptr GetPreviousInstructionPc(uptr pc);
+
+ private:
void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom,
uptr max_depth);
void SlowUnwindStack(uptr pc, uptr max_depth);
-
void PopStackFrames(uptr count);
-
- static uptr GetCurrentPc();
- static uptr GetPreviousInstructionPc(uptr pc);
};
} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
index 8ce0918d..a8e70c96 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
@@ -16,14 +16,8 @@
namespace __sanitizer {
void StackTrace::Unwind(uptr max_depth, uptr pc, uptr bp, uptr stack_top,
- uptr stack_bottom, bool fast) {
- // Check if fast unwind is available. Fast unwind is the only option on Mac.
- if (!SANITIZER_CAN_FAST_UNWIND)
- fast = false;
- else if (SANITIZER_MAC)
- fast = true;
-
- if (!fast)
+ uptr stack_bottom, bool request_fast_unwind) {
+ if (!WillUseFastUnwind(request_fast_unwind))
SlowUnwindStack(pc, max_depth);
else
FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);
diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
index 8d2ac2bd..5e6d3fdb 100644
--- a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
@@ -20,6 +20,13 @@ namespace __sanitizer {
class FastUnwindTest : public ::testing::Test {
protected:
virtual void SetUp();
+ bool TryFastUnwind(uptr max_depth) {
+ if (!StackTrace::WillUseFastUnwind(true))
+ return false;
+ trace.Unwind(max_depth, start_pc, (uptr)&fake_stack[0], fake_top,
+ fake_bottom, true);
+ return true;
+ }
uptr fake_stack[10];
uptr start_pc;
@@ -50,8 +57,8 @@ void FastUnwindTest::SetUp() {
}
TEST_F(FastUnwindTest, Basic) {
- trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
- fake_top, fake_bottom, kStackTraceMax);
+ if (!TryFastUnwind(kStackTraceMax))
+ return;
// Should get all on-stack retaddrs and start_pc.
EXPECT_EQ(6U, trace.size);
EXPECT_EQ(start_pc, trace.trace[0]);
@@ -64,8 +71,8 @@ TEST_F(FastUnwindTest, Basic) {
TEST_F(FastUnwindTest, FramePointerLoop) {
// Make one fp point to itself.
fake_stack[4] = (uptr)&fake_stack[4];
- trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
- fake_top, fake_bottom, kStackTraceMax);
+ if (!TryFastUnwind(kStackTraceMax))
+ return;
// Should get all on-stack retaddrs up to the 4th slot and start_pc.
EXPECT_EQ(4U, trace.size);
EXPECT_EQ(start_pc, trace.trace[0]);
@@ -77,8 +84,8 @@ TEST_F(FastUnwindTest, FramePointerLoop) {
TEST_F(FastUnwindTest, MisalignedFramePointer) {
// Make one fp misaligned.
fake_stack[4] += 3;
- trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
- fake_top, fake_bottom, kStackTraceMax);
+ if (!TryFastUnwind(kStackTraceMax))
+ return;
// Should get all on-stack retaddrs up to the 4th slot and start_pc.
EXPECT_EQ(4U, trace.size);
EXPECT_EQ(start_pc, trace.trace[0]);
@@ -88,8 +95,8 @@ TEST_F(FastUnwindTest, MisalignedFramePointer) {
}
TEST_F(FastUnwindTest, OneFrameStackTrace) {
- trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
- fake_top, fake_bottom, 1);
+ if (!TryFastUnwind(1))
+ return;
EXPECT_EQ(1U, trace.size);
EXPECT_EQ(start_pc, trace.trace[0]);
}
diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc
index c353cea8..4fed43fa 100644
--- a/lib/tsan/rtl/tsan_rtl_report.cc
+++ b/lib/tsan/rtl/tsan_rtl_report.cc
@@ -726,8 +726,8 @@ void PrintCurrentStackSlow() {
#ifndef TSAN_GO
__sanitizer::StackTrace *ptrace = new(internal_alloc(MBlockStackTrace,
sizeof(__sanitizer::StackTrace))) __sanitizer::StackTrace;
- ptrace->SlowUnwindStack(__sanitizer::StackTrace::GetCurrentPc(),
- kStackTraceMax);
+ ptrace->Unwind(kStackTraceMax, __sanitizer::StackTrace::GetCurrentPc(),
+ 0, 0, 0, false);
for (uptr i = 0; i < ptrace->size / 2; i++) {
uptr tmp = ptrace->trace[i];
ptrace->trace[i] = ptrace->trace[ptrace->size - i - 1];