forked from OSchip/llvm-project
[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:
parent
90a835d2a0
commit
1f1c7ec400
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue