[Sanitizers] Share some stack walking code between Windows and Linux

Reviewed at http://llvm-reviews.chandlerc.com/D2126

llvm-svn: 194326
This commit is contained in:
Timur Iskhodzhanov 2013-11-09 13:59:12 +00:00
parent 90a835d2a0
commit 1f1c7ec400
4 changed files with 23 additions and 23 deletions

View File

@ -154,10 +154,6 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
return UNWIND_CONTINUE;
}
static bool MatchPc(uptr cur_pc, uptr trace_pc) {
return cur_pc - trace_pc <= 64 || trace_pc - cur_pc <= 64;
}
void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
size = 0;
if (max_depth == 0)
@ -165,13 +161,10 @@ void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
_Unwind_Backtrace(Unwind_Trace, &arg);
// We need to pop a few frames so that pc is on top.
uptr to_pop = LocatePcInTrace(pc, 64, 6);
// trace[0] belongs to the current function so we always pop it.
int to_pop = 1;
/**/ if (size > 1 && MatchPc(pc, trace[1])) to_pop = 1;
else if (size > 2 && MatchPc(pc, trace[2])) to_pop = 2;
else if (size > 3 && MatchPc(pc, trace[3])) to_pop = 3;
else if (size > 4 && MatchPc(pc, trace[4])) to_pop = 4;
else if (size > 5 && MatchPc(pc, trace[5])) to_pop = 5;
if (to_pop == 0)
to_pop = 1;
PopStackFrames(to_pop);
trace[0] = pc;
}

View File

@ -147,4 +147,17 @@ void StackTrace::PopStackFrames(uptr count) {
}
}
static bool MatchPc(uptr cur_pc, uptr trace_pc, uptr threshold) {
return cur_pc - trace_pc <= threshold || trace_pc - cur_pc <= threshold;
}
uptr
StackTrace::LocatePcInTrace(uptr pc, uptr pc_threshold, uptr max_pc_depth) {
for (uptr i = 0; i < max_pc_depth && i < size; ++i) {
if (MatchPc(pc, trace[i], pc_threshold))
return i;
}
return 0;
}
} // namespace __sanitizer

View File

@ -67,6 +67,7 @@ struct StackTrace {
uptr max_depth);
void SlowUnwindStack(uptr pc, uptr max_depth);
void PopStackFrames(uptr count);
uptr LocatePcInTrace(uptr pc, uptr pc_threshold = 0, uptr max_pc_depth = -1);
};
} // namespace __sanitizer

View File

@ -377,23 +377,16 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
}
void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
void *tmp[kStackTraceMax];
// FIXME: CaptureStackBackTrace might be too slow for us.
// FIXME: Compare with StackWalk64.
// FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc
uptr cs_ret = CaptureStackBackTrace(2, max_depth, tmp, 0);
uptr offset = 0;
size = CaptureStackBackTrace(2, Min(max_depth, kStackTraceMax),
(void**)trace, 0);
// Skip the RTL frames by searching for the PC in the stacktrace.
// FIXME: this doesn't work well for the malloc/free stacks yet.
for (uptr i = 0; i < cs_ret; i++) {
if (pc != (uptr)tmp[i])
continue;
offset = i;
break;
}
CopyFrom((uptr*)&tmp[offset], cs_ret - offset);
// FIXME: this doesn't work well for the malloc/free stacks yet - consider
// adjusting the pc_threshold.
uptr pc_location = LocatePcInTrace(pc);
PopStackFrames(pc_location);
}
void MaybeOpenReportFile() {