summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Saleem Abdulrasool <abdulras@google.com>2022-06-30 15:34:32 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-06-30 15:36:12 -0700
commitf4988f5bd4176345aad2a525e24d5fd11b3c97ea (patch)
tree1d79c2e6e3b738e91e92a00d16190963e661eff6
parentb35ae3281ac7be49b42dc574403ff5fbcf1788fb (diff)
debugging: account for differences in alternate signal stacks
The alternate signal stack may be sufficiently beyond the esimated frame size (100k). If we run into the case that the frame is not in the correct direction assume that the frames may be non-contiguous due to an alternate signal stack layout. In such a case, if we find that there is an alternate stack configured, ignore the discontiuity (assuming that it is a removable point-wise discontinuity) and continue the stack unwinding. This permits us to capture stack traces in more cases. PiperOrigin-RevId: 458327775 Change-Id: Ia8b461847401492f72a23ba26601c72e0109402c
-rw-r--r--absl/debugging/internal/stacktrace_riscv-inl.inc15
1 files changed, 15 insertions, 0 deletions
diff --git a/absl/debugging/internal/stacktrace_riscv-inl.inc b/absl/debugging/internal/stacktrace_riscv-inl.inc
index 7123b71b..ba0775b2 100644
--- a/absl/debugging/internal/stacktrace_riscv-inl.inc
+++ b/absl/debugging/internal/stacktrace_riscv-inl.inc
@@ -159,6 +159,21 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc) {
const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
const uintptr_t frame_size =
ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
+
+ // If we have a alternate signal stack, the stack pointer may not be
+ // contiguous. In such a case, we can simply skip the check and assume that
+ // the non-contiguity is permissible.
+ if (frame_size == kUnknownFrameSize) {
+ assert(old_frame_pointer >= new_frame_pointer);
+
+ stack_t ss{};
+ if (sigaltstack(nullptr, &ss) == 0) {
+ if (ss.ss_flags & SS_DISABLE)
+ return nullptr;
+ return new_frame_pointer;
+ }
+ }
+
if (frame_size == kUnknownFrameSize || frame_size > max_size)
return nullptr;
}