diff options
author | Saleem Abdulrasool <abdulras@google.com> | 2022-07-29 14:38:13 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-07-29 14:39:07 -0700 |
commit | dc370a82467cb35066475537b797197aee3e5164 (patch) | |
tree | 742841c210ccb7b83a432e780d475bbfe94b85b9 /absl | |
parent | 7f51ef5ed2740dab2bbf53c4dd5931b6e8ec6a5b (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')
-rw-r--r-- | absl/debugging/internal/stacktrace_riscv-inl.inc | 40 |
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; } |