summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.cc8
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h7
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc3
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc2
-rw-r--r--compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc13
5 files changed, 25 insertions, 8 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc
index 8aea7bcdbcf..79fcbb1183f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc
@@ -25,13 +25,7 @@ namespace __sanitizer {
const char *SanitizerToolName = "SanitizerTool";
atomic_uint32_t current_verbosity;
-
-uptr GetPageSizeCached() {
- static uptr PageSize;
- if (!PageSize)
- PageSize = GetPageSize();
- return PageSize;
-}
+uptr PageSizeCached;
StaticSpinMutex report_file_mu;
ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0};
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 24ef93a9ce1..6c1d6a00a10 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -63,7 +63,12 @@ INLINE int Verbosity() {
}
uptr GetPageSize();
-uptr GetPageSizeCached();
+extern uptr PageSizeCached;
+INLINE uptr GetPageSizeCached() {
+ if (!PageSizeCached)
+ PageSizeCached = GetPageSize();
+ return PageSizeCached;
+}
uptr GetMmapGranularity();
uptr GetMaxVirtualAddress();
// Threads
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
index bf5456fc277..8a3fa1c1db2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
@@ -66,6 +66,7 @@ static inline uhwptr *GetCanonicFrame(uptr bp,
void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
uptr stack_bottom, u32 max_depth) {
+ const uptr kPageSize = GetPageSizeCached();
CHECK_GE(max_depth, 2);
trace_buffer[0] = pc;
size = 1;
@@ -92,6 +93,8 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
#else
uhwptr pc1 = frame[1];
#endif
+ if (pc1 < kPageSize)
+ break;
if (pc1 != pc) {
trace_buffer[size++] = (uptr) pc1;
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
index f38886acd54..c9dfb8a0ead 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
@@ -108,6 +108,8 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
UnwindTraceArg *arg = (UnwindTraceArg*)param;
CHECK_LT(arg->stack->size, arg->max_depth);
uptr pc = Unwind_GetIP(ctx);
+ const uptr kPageSize = GetPageSizeCached();
+ if (pc < kPageSize) return UNWIND_STOP;
arg->stack->trace_buffer[arg->stack->size++] = pc;
if (arg->stack->size == arg->max_depth) return UNWIND_STOP;
return UNWIND_CONTINUE;
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
index 3d57eded948..ba9f4fd6932 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
@@ -136,6 +136,19 @@ TEST_F(FastUnwindTest, FPBelowPrevFP) {
EXPECT_EQ(PC(1), trace.trace[1]);
}
+TEST_F(FastUnwindTest, CloseToZeroFrame) {
+ // Make one pc a NULL pointer.
+ fake_stack[5] = 0x0;
+ if (!TryFastUnwind(kStackTraceMax))
+ return;
+ // The stack should be truncated at the NULL pointer (and not include it).
+ EXPECT_EQ(3U, trace.size);
+ EXPECT_EQ(start_pc, trace.trace[0]);
+ for (uptr i = 1; i < 3U; i++) {
+ EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);
+ }
+}
+
TEST(SlowUnwindTest, ShortStackTrace) {
if (StackTrace::WillUseFastUnwind(false))
return;
OpenPOWER on IntegriCloud