summaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/stacktrace_riscv-inl.inc78
1 files changed, 9 insertions, 69 deletions
diff --git a/absl/debugging/internal/stacktrace_riscv-inl.inc b/absl/debugging/internal/stacktrace_riscv-inl.inc
index a0f23739..a9e2c323 100644
--- a/absl/debugging/internal/stacktrace_riscv-inl.inc
+++ b/absl/debugging/internal/stacktrace_riscv-inl.inc
@@ -32,54 +32,10 @@
#include <iostream>
#include "absl/base/attributes.h"
-#include "absl/debugging/internal/address_is_readable.h"
-#include "absl/debugging/internal/vdso_support.h"
#include "absl/debugging/stacktrace.h"
static const uintptr_t kUnknownFrameSize = 0;
-#if defined(__linux__)
-// Returns the address of the VDSO __kernel_rt_sigreturn function, if present.
-static const unsigned char *GetKernelRtSigreturnAddress() {
- constexpr uintptr_t kImpossibleAddress = 0;
- ABSL_CONST_INIT static std::atomic<uintptr_t> memoized(kImpossibleAddress);
- uintptr_t address = memoized.load(std::memory_order_relaxed);
- if (address != kImpossibleAddress) {
- return reinterpret_cast<const unsigned char *>(address);
- }
-
- address = reinterpret_cast<uintptr_t>(nullptr);
-
-#if ABSL_HAVE_VDSO_SUPPORT
- absl::debugging_internal::VDSOSupport vdso;
- if (vdso.IsPresent()) {
- absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info;
- // Symbol versioning pulled from arch/riscv/kernel/vdso/vdso.lds at v5.10.
- auto lookup = [&](int type) {
- return vdso.LookupSymbol("__vdso_rt_sigreturn", "LINUX_4.15", type,
- &symbol_info);
- };
- if ((!lookup(STT_FUNC) && !lookup(STT_NOTYPE)) ||
- symbol_info.address == nullptr) {
- // Unexpected: VDSO is present, yet the expected symbol is missing or
- // null.
- assert(false && "VDSO is present, but doesn't have expected symbol");
- } else {
- if (reinterpret_cast<uintptr_t>(symbol_info.address) !=
- kImpossibleAddress) {
- address = reinterpret_cast<uintptr_t>(symbol_info.address);
- } else {
- assert(false && "VDSO returned invalid address");
- }
- }
- }
-#endif
-
- memoized.store(address, std::memory_order_relaxed);
- return reinterpret_cast<const unsigned char *>(address);
-}
-#endif // __linux__
-
// Compute the size of a stack frame in [low..high). We assume that low < high.
// Return size of kUnknownFrameSize.
template <typename T>
@@ -115,40 +71,23 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
// $sp ->| ... |
// +----------------+
void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]);
+ uintptr_t frame_pointer = reinterpret_cast<uintptr_t>(new_frame_pointer);
// 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)
+ if (frame_pointer & 15)
return nullptr;
-#if defined(__linux__)
- if (WITH_CONTEXT && uc != nullptr) {
- // Check to see if next frame's return address is __kernel_rt_sigreturn.
- if (old_frame_pointer[-1] == GetKernelRtSigreturnAddress()) {
- const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
- // old_frame_pointer is not suitable for unwinding, look at ucontext to
- // discover frame pointer before signal.
- //
+ // If the new frame pointer matches the signal context, avoid terminating
+ // early to deal with alternate signal stacks.
+ if (WITH_CONTEXT)
+ if (const ucontext_t *ucv = static_cast<const ucontext_t *>(uc))
// RISCV ELF psABI has the frame pointer at x8/fp/s0.
// -- RISCV psABI Table 18.2
- void **const pre_signal_frame_pointer =
- reinterpret_cast<void **>(ucv->uc_mcontext.__gregs[8]);
-
- // Check the alleged frame pointer is actually readable. This is to
- // prevent "double fault" in case we hit the first fault due to stack
- // corruption.
- if (!absl::debugging_internal::AddressIsReadable(
- pre_signal_frame_pointer))
- return nullptr;
-
- // Alleged frame pointer is readable, use it for further unwinding.
- new_frame_pointer = pre_signal_frame_pointer;
- }
- return new_frame_pointer;
- }
-#endif
+ if (ucv->uc_mcontext.__gregs[8] == frame_pointer)
+ return new_frame_pointer;
// 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.
@@ -165,6 +104,7 @@ static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
reinterpret_cast<uintptr_t>(new_frame_pointer) > range.second)
return nullptr;
}
+
if (frame_size > max_size)
return nullptr;