From 2d31912897d4b4a72424368154d37f05c93677cb Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 30 Mar 2023 11:00:26 -0700 Subject: Properly calculate frame sizes on Aarch64 For function N in the stack, the current code reports the size of frame N - 1. Fix that. PiperOrigin-RevId: 520688072 Change-Id: I984729f72f79aebae1b6997cb51d3ddef9199d1e --- absl/debugging/internal/stacktrace_aarch64-inl.inc | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'absl/debugging/internal') diff --git a/absl/debugging/internal/stacktrace_aarch64-inl.inc b/absl/debugging/internal/stacktrace_aarch64-inl.inc index 71cdaf09..4fc87f51 100644 --- a/absl/debugging/internal/stacktrace_aarch64-inl.inc +++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc @@ -138,7 +138,6 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, #else # error reading stack point not yet supported on this platform. #endif - skip_count++; // Skip the frame for this function. int n = 0; @@ -151,29 +150,33 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, // does not work for the first stack frame, which belongs to UnwindImp() but // we skip the frame for UnwindImp() anyway. void* prev_return_address = nullptr; + // The nth frame size is the difference between the nth frame pointer and the + // the frame pointer below it in the call chain. There is no frame below the + // leaf frame, but this function is the leaf anyway, and we skip it. + void** prev_frame_pointer = nullptr; - while (frame_pointer && n < max_depth) { - // The absl::GetStackFrames routine is called when we are in some - // informational context (the failure signal handler for example). - // Use the non-strict unwinding rules to produce a stack trace - // that is as complete as possible (even if it contains a few bogus - // entries in some rare cases). - void **next_frame_pointer = - NextStackFrame(frame_pointer, ucp); - + while (frame_pointer && n < max_depth) { if (skip_count > 0) { skip_count--; } else { result[n] = prev_return_address; if (IS_STACK_FRAMES) { sizes[n] = static_cast( - ComputeStackFrameSize(frame_pointer, next_frame_pointer)); + ComputeStackFrameSize(prev_frame_pointer, frame_pointer)); } n++; } prev_return_address = frame_pointer[1]; - frame_pointer = next_frame_pointer; + prev_frame_pointer = frame_pointer; + // The absl::GetStackFrames routine is called when we are in some + // informational context (the failure signal handler for example). + // Use the non-strict unwinding rules to produce a stack trace + // that is as complete as possible (even if it contains a few bogus + // entries in some rare cases). + frame_pointer = + NextStackFrame(frame_pointer, ucp); } + if (min_dropped_frames != nullptr) { // Implementation detail: we clamp the max of frames we are willing to // count, so as not to spend too much time in the loop below. -- cgit v1.2.3