Avoid doing any work when unwinding stack traces with 0 or 1 frame

llvm-svn: 202837
This commit is contained in:
Alexey Samsonov 2014-03-04 12:21:28 +00:00
parent 7288503bd5
commit 3e8467b8b9
4 changed files with 17 additions and 12 deletions

View File

@ -223,9 +223,8 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
}
void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
CHECK_GE(max_depth, 2);
size = 0;
if (max_depth == 0)
return;
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.
@ -239,14 +238,12 @@ void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
void StackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
uptr max_depth) {
CHECK_GE(max_depth, 2);
if (!unwind_backtrace_signal_arch) {
SlowUnwindStack(pc, max_depth);
return;
}
size = 0;
if (max_depth == 0) return;
void *map = acquire_my_map_info_list();
CHECK(map);
InternalScopedBuffer<backtrace_frame_t> frames(kStackTraceMax);
@ -256,8 +253,9 @@ void StackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
/* ignore_depth */ 0, max_depth);
release_my_map_info_list(map);
if (res < 0) return;
CHECK((uptr)res <= kStackTraceMax);
CHECK_LE((uptr)res, kStackTraceMax);
size = 0;
// +2 compensate for libcorkscrew unwinder returning addresses of call
// instructions instead of raw return addresses.
for (sptr i = 0; i < res; ++i)

View File

@ -36,10 +36,7 @@ uptr StackTrace::GetCurrentPc() {
void StackTrace::FastUnwindStack(uptr pc, uptr bp,
uptr stack_top, uptr stack_bottom,
uptr max_depth) {
if (max_depth == 0) {
size = 0;
return;
}
CHECK_GE(max_depth, 2);
trace[0] = pc;
size = 1;
uptr *frame = (uptr *)bp;

View File

@ -66,6 +66,17 @@ void StackTrace::PrintStack(const uptr *addr, uptr size) {
void StackTrace::Unwind(uptr max_depth, uptr pc, uptr bp, void *context,
uptr stack_top, uptr stack_bottom,
bool request_fast_unwind) {
top_frame_bp = (max_depth > 0) ? bp : 0;
// Avoid doing any work for small max_depth.
if (max_depth == 0) {
size = 0;
return;
}
if (max_depth == 1) {
size = 1;
trace[0] = pc;
return;
}
if (!WillUseFastUnwind(request_fast_unwind)) {
if (context)
SlowUnwindStackWithContext(pc, context, max_depth);
@ -74,8 +85,6 @@ void StackTrace::Unwind(uptr max_depth, uptr pc, uptr bp, void *context,
} else {
FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);
}
top_frame_bp = size ? bp : 0;
}
} // namespace __sanitizer

View File

@ -417,6 +417,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
}
void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
CHECK_GE(max_depth, 2);
// FIXME: CaptureStackBackTrace might be too slow for us.
// FIXME: Compare with StackWalk64.
// FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc