forked from OSchip/llvm-project
Avoid doing any work when unwinding stack traces with 0 or 1 frame
llvm-svn: 202837
This commit is contained in:
parent
7288503bd5
commit
3e8467b8b9
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue