diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 6359f4348e3c4..1da3ce763302e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -107,7 +107,9 @@ extern struct ps_strings *__ps_strings; # endif // SANITIZER_NETBSD # if SANITIZER_SOLARIS +# include # include +# include # include # define environ _environ # endif @@ -2617,7 +2619,19 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { # if SANITIZER_SOLARIS ucontext_t *ucontext = (ucontext_t *)context; *pc = ucontext->uc_mcontext.gregs[REG_PC]; - *sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS; + *sp = ucontext->uc_mcontext.gregs[REG_SP] + STACK_BIAS; + // Avoid SEGV when dereferencing sp on stack overflow with non-faulting load. + // This requires a SPARC V9 CPU. Cannot use #ASI_PNF here: only supported + // since clang-19. +# if defined(__sparcv9) + asm("ldxa [%[fp]] 0x82, %[bp]" +# else + asm("lduwa [%[fp]] 0x82, %[bp]" +# endif + : [bp] "=r"(*bp) + : [fp] "r"(&((struct frame *)*sp)->fr_savfp)); + if (*bp) + *bp += STACK_BIAS; # else // Historical BSDism here. struct sigcontext *scontext = (struct sigcontext *)context; @@ -2628,8 +2642,8 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = scontext->si_regs.pc; *sp = scontext->si_regs.u_regs[14]; # endif -# endif *bp = (uptr)((uhwptr *)*sp)[14] + STACK_BIAS; +# endif # elif defined(__mips__) ucontext_t *ucontext = (ucontext_t *)context; *pc = ucontext->uc_mcontext.pc; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index ffbaf1468ec8f..351e00db6fb2d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -227,12 +227,15 @@ static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid, SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc, (void *)sig.bp, (void *)sig.sp, tid); Printf("%s", d.Default()); - InternalMmapVector stack_buffer(1); - BufferedStackTrace *stack = stack_buffer.data(); - stack->Reset(); - unwind(sig, unwind_context, stack); - stack->Print(); - ReportErrorSummary(kDescription, stack); + // Avoid SEGVs in the unwinder when bp couldn't be determined. + if (sig.bp) { + InternalMmapVector stack_buffer(1); + BufferedStackTrace *stack = stack_buffer.data(); + stack->Reset(); + unwind(sig, unwind_context, stack); + stack->Print(); + ReportErrorSummary(kDescription, stack); + } } static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,