Skip to content

Commit

Permalink
[sanitizer] Stop unwinding the stack when a close-to-zero PC is found
Browse files Browse the repository at this point in the history
On OS X, we often get stack trace in a report that ends with a 0x0 frame.  To get rid of it, let's trim the stack trace when we find a close-to-zero value, which is obviously not a valid PC.

Differential Revision: http://reviews.llvm.org/D14656

llvm-svn: 273886
  • Loading branch information
kubamracek committed Jun 27, 2016
1 parent 5da24e5 commit 02478f4
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 8 deletions.
8 changes: 1 addition & 7 deletions compiler-rt/lib/sanitizer_common/sanitizer_common.cc
Expand Up @@ -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};
Expand Down
7 changes: 6 additions & 1 deletion compiler-rt/lib/sanitizer_common/sanitizer_common.h
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cc
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
Expand Up @@ -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;
Expand Down
Expand Up @@ -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;
Expand Down

0 comments on commit 02478f4

Please sign in to comment.