summaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
authorGravatar Saleem Abdulrasool <abdulras@google.com>2022-07-29 14:38:13 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-07-29 14:39:07 -0700
commitdc370a82467cb35066475537b797197aee3e5164 (patch)
tree742841c210ccb7b83a432e780d475bbfe94b85b9 /absl/debugging
parent7f51ef5ed2740dab2bbf53c4dd5931b6e8ec6a5b (diff)
debugging: honour `STRICT_UNWINDING` in RISCV path
The changes in d6f96eda14aca77748a439f05a567a46ce87e462 enabled handling cases where the stack may be non-contiguous or not fully symbolicated (e.g. in cases of alternate signal stacks). However, it did not properly honour the requests from the caller to perform a strict unwinding where such frames are terminated upon the discontinuity. This repairs that condition. Hoist the alignment check since that is safe to perform early. PiperOrigin-RevId: 464160529 Change-Id: Ic65645928ec60c2a3b4844f3abd4fed1b991edab
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/stacktrace_riscv-inl.inc40
1 files changed, 20 insertions, 20 deletions
diff --git a/absl/debugging/internal/stacktrace_riscv-inl.inc b/absl/debugging/internal/stacktrace_riscv-inl.inc
index 70b11e5e..a0f23739 100644
--- a/absl/debugging/internal/stacktrace_riscv-inl.inc
+++ b/absl/debugging/internal/stacktrace_riscv-inl.inc
@@ -115,7 +115,13 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
// $sp ->| ... |
// +----------------+
void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]);
- bool check_frame_size = true;
+
+ // The RISCV ELF psABI mandates that the stack pointer is always 16-byte
+ // aligned.
+ // TODO(#1236) this doesn't hold for ILP32E which only mandates a 4-byte
+ // alignment.
+ if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0)
+ return nullptr;
#if defined(__linux__)
if (WITH_CONTEXT && uc != nullptr) {
@@ -139,34 +145,28 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
// Alleged frame pointer is readable, use it for further unwinding.
new_frame_pointer = pre_signal_frame_pointer;
-
- // Skip frame size check if we return from a signal. We may be using an
- // alterate stack for signals.
- check_frame_size = false;
}
+ return new_frame_pointer;
}
#endif
- // The RISCV ELF psABI mandates that the stack pointer is always 16-byte
- // aligned.
- // FIXME(abdulras) this doesn't hold for ILP32E which only mandates a 4-byte
- // alignment.
- if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0)
- return nullptr;
-
// Check frame size. In strict mode, we assume frames to be under 100,000
// bytes. In non-strict mode, we relax the limit to 1MB.
- if (check_frame_size) {
- const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
- const uintptr_t frame_size =
- ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
- if (frame_size == kUnknownFrameSize &&
- (reinterpret_cast<uintptr_t>(new_frame_pointer) < range.first ||
- reinterpret_cast<uintptr_t>(new_frame_pointer) > range.second))
+ const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
+ const uintptr_t frame_size =
+ ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
+ if (frame_size == kUnknownFrameSize) {
+ if (STRICT_UNWINDING)
return nullptr;
- if (frame_size > max_size)
+
+ // In non-strict mode permit non-contiguous stacks (e.g. alternate signal
+ // frame handling).
+ if (reinterpret_cast<uintptr_t>(new_frame_pointer) < range.first ||
+ reinterpret_cast<uintptr_t>(new_frame_pointer) > range.second)
return nullptr;
}
+ if (frame_size > max_size)
+ return nullptr;
return new_frame_pointer;
}