Commit 2d319128 by Abseil Team Committed by Copybara-Service

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
parent 61b059f7
...@@ -138,7 +138,6 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, ...@@ -138,7 +138,6 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
#else #else
# error reading stack point not yet supported on this platform. # error reading stack point not yet supported on this platform.
#endif #endif
skip_count++; // Skip the frame for this function. skip_count++; // Skip the frame for this function.
int n = 0; int n = 0;
...@@ -151,29 +150,33 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, ...@@ -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 // does not work for the first stack frame, which belongs to UnwindImp() but
// we skip the frame for UnwindImp() anyway. // we skip the frame for UnwindImp() anyway.
void* prev_return_address = nullptr; 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) { 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<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
if (skip_count > 0) { if (skip_count > 0) {
skip_count--; skip_count--;
} else { } else {
result[n] = prev_return_address; result[n] = prev_return_address;
if (IS_STACK_FRAMES) { if (IS_STACK_FRAMES) {
sizes[n] = static_cast<int>( sizes[n] = static_cast<int>(
ComputeStackFrameSize(frame_pointer, next_frame_pointer)); ComputeStackFrameSize(prev_frame_pointer, frame_pointer));
} }
n++; n++;
} }
prev_return_address = frame_pointer[1]; 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<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
} }
if (min_dropped_frames != nullptr) { if (min_dropped_frames != nullptr) {
// Implementation detail: we clamp the max of frames we are willing to // 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. // count, so as not to spend too much time in the loop below.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment