summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Iskhodzhanov <timurrrr@google.com>2013-11-09 13:59:12 +0000
committerTimur Iskhodzhanov <timurrrr@google.com>2013-11-09 13:59:12 +0000
commit7177d2bbb5850fb499d3e8910b2e05f5c6b025b0 (patch)
tree4ebee1c8404b35438fe46f7d651f60acefc7081d
parent49496747758bf44163768ce3e07e40c8f95ccba9 (diff)
downloadcompiler-rt-7177d2bbb5850fb499d3e8910b2e05f5c6b025b0.tar.gz
compiler-rt-7177d2bbb5850fb499d3e8910b2e05f5c6b025b0.tar.bz2
compiler-rt-7177d2bbb5850fb499d3e8910b2e05f5c6b025b0.tar.xz
[Sanitizers] Share some stack walking code between Windows and Linux
Reviewed at http://llvm-reviews.chandlerc.com/D2126 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@194326 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc13
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.cc13
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.h1
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc19
4 files changed, 23 insertions, 23 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index d415279d..eba6eb96 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -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;
}
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cc
index a110774e..f03490b8 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace.cc
@@ -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
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.h b/lib/sanitizer_common/sanitizer_stacktrace.h
index 035f39f8..408063c1 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -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
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index d8a57d53..7d07a173 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -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() {