@@ -245,6 +245,7 @@ static void **NextStackFrame(void **old_fp, const void *uc,
245245 }
246246# endif
247247
248+ const size_t page_size = static_cast< size_t> (getpagesize ());
248249 const uintptr_t old_fp_u = reinterpret_cast< uintptr_t> (old_fp);
249250 const uintptr_t new_fp_u = reinterpret_cast< uintptr_t> (new_fp);
250251
@@ -273,8 +274,7 @@ static void **NextStackFrame(void **old_fp, const void *uc,
273274 // so we assume the large frame is legit if we know the real stack bounds
274275 // and are within the stack.
275276 if (new_fp_u <= old_fp_u || new_fp_u - old_fp_u > kMaxFrameBytes) {
276- if (stack_high < kUnknownStackEnd &&
277- static_cast< size_t> (getpagesize ()) < stack_low) {
277+ if (stack_high < kUnknownStackEnd && page_size < stack_low) {
278278 // Stack bounds are known.
279279 if (! (stack_low < new_fp_u && new_fp_u <= stack_high)) {
280280 // new_fp_u is not within the known stack.
@@ -311,7 +311,12 @@ static void **NextStackFrame(void **old_fp, const void *uc,
311311 if (new_fp_u >= 0xffffe000 ) return nullptr;
312312# endif
313313# if !defined(_WIN32)
314- if (! STRICT_UNWINDING) {
314+ const uintptr_t old_fp_page = old_fp_u & ~ (page_size - 1 );
315+ const uintptr_t new_fp_page = new_fp_u & ~ (page_size - 1 );
316+ if (old_fp_page == new_fp_page && (new_fp_u & (sizeof (void* ) - 1 )) == 0 ) {
317+ // We dereferenced the old_fp above, so it is safe to dereference
318+ // new_fp if it's on the same page as the old_fp and is aligned.
319+ } else if (! STRICT_UNWINDING) {
315320 // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test
316321 // on AMD-based machines with VDSO-enabled kernels.
317322 // Make an extra sanity check to insure new_fp is readable.
0 commit comments