debugging: add hooks for checking stack ranges

Add a hook to permit checking whether an address is in bounds for the stack.

PiperOrigin-RevId: 460997074
Change-Id: Ib3b4d0cf656e614aa083457abb079c40ef8db0ff
pull/1223/head
Saleem Abdulrasool 3 years ago committed by Copybara-Service
parent ef68bd3d31
commit d6f96eda14
  1. 21
      absl/debugging/internal/stacktrace_riscv-inl.inc

@ -96,7 +96,8 @@ static inline uintptr_t ComputeStackFrameSize(const T *low, const T *high) {
template <bool STRICT_UNWINDING, bool WITH_CONTEXT>
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack.
static void ** NextStackFrame(void **old_frame_pointer, const void *uc) {
static void ** NextStackFrame(void **old_frame_pointer, const void *uc,
const std::pair<size_t, size_t> range) {
// .
// .
// .
@ -159,7 +160,11 @@ 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 (frame_size == kUnknownFrameSize || frame_size > max_size)
if (frame_size == kUnknownFrameSize &&
(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;
}
@ -180,6 +185,12 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
#error reading stack pointer not yet supported on this platform
#endif
std::pair<size_t, size_t> stack = {
// assume that the first page is not the stack.
static_cast<size_t>(sysconf(_SC_PAGESIZE)),
std::numeric_limits<size_t>::max() - sizeof(void *)
};
int n = 0;
void *return_address = nullptr;
while (frame_pointer && n < max_depth) {
@ -190,7 +201,8 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
// 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);
NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp,
stack);
if (skip_count > 0) {
skip_count--;
@ -217,7 +229,8 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
num_dropped_frames++;
}
frame_pointer =
NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp,
stack);
}
*min_dropped_frames = num_dropped_frames;
}

Loading…
Cancel
Save