# HG changeset patch # User Taylor R Campbell # Date 1744487837 0 # Sat Apr 12 19:57:17 2025 +0000 # Branch trunk # Node ID d857f250705966f1fb6141eae04307965f26134b # Parent 04218384223d82cd5e3facb3ebb61bc9184838f0 # EXP-Topic riastradh-pr57946-longjmpstacksigmask hppa longjmp: Use _UC_SIGMASK to restore signal mask. This way, restoring the signal mask and restoring the stack pointer happen atomically with respect to signal handler calls, whereas using sigprocmask would restore the signal mask _before_ the stack pointer, breaking sigaltstack. The motivation for using sigprocmask first and then setcontext later, rather than _UC_SIGMASK in setcontext, was to get SA-based libpthead sigprocmask interposition. But that's long gone and unlikely to come back. PR lib/57946: longjmp fails to restore stack first before restoring signal mask on most architectures diff -r 04218384223d -r d857f2507059 lib/libc/arch/hppa/gen/__longjmp14.c --- a/lib/libc/arch/hppa/gen/__longjmp14.c Sat Apr 12 13:00:21 2025 +0000 +++ b/lib/libc/arch/hppa/gen/__longjmp14.c Sat Apr 12 19:57:17 2025 +0000 @@ -88,14 +88,21 @@ void uc.uc_mcontext.__gregs[_REG_RET0] = val; /* - * Set _UC_{SET,CLR}STACK according to SS_ONSTACK. + * Set _UC_CPU (restore CPU registers) and _UC_SIGMASK (restore + * the signal mask) unconditionally. * - * Restore the signal mask with sigprocmask() instead of _UC_SIGMASK, - * since libpthread may want to interpose on signal handling. + * In the distant past of SA-based libpthread with sigprocmask + * interception, we called sigprocmask here instead of using + * _UC_SIGMASK -- but that restored the signal mask before the + * stack pointer (PR lib/57946: longjmp fails to restore stack + * first before restoring signal mask on most architectures), + * which breaks sigaltstack, and SA-based libpthread is long + * gone. So we use _UC_SIGMASK. + * + * Set _UC_{SET,CLR}STACK according to SS_ONSTACK. */ - uc.uc_flags = _UC_CPU | (sc->sc_onstack ? _UC_SETSTACK : _UC_CLRSTACK); - - sigprocmask(SIG_SETMASK, &sc->sc_mask, NULL); + uc.uc_flags = _UC_CPU | _UC_SIGMASK; + uc.uc_flags |= (sc->sc_onstack ? _UC_SETSTACK : _UC_CLRSTACK); /* Clear uc_link */ uc.uc_link = 0; diff -r 04218384223d -r d857f2507059 tests/lib/libc/setjmp/t_sigstack.c --- a/tests/lib/libc/setjmp/t_sigstack.c Sat Apr 12 13:00:21 2025 +0000 +++ b/tests/lib/libc/setjmp/t_sigstack.c Sat Apr 12 19:57:17 2025 +0000 @@ -84,6 +84,7 @@ on_sigusr1(int signo, siginfo_t *si, voi * aarch64 * alpha * arm + * hppa * i386 * m68k * or1k @@ -93,7 +94,7 @@ on_sigusr1(int signo, siginfo_t *si, voi * vax * x86_64 */ -#if defined __hppa__ || \ +#if \ defined __ia64__ || defined __mips__ || \ defined __sparc__ || defined __sparc64__ if (nentries > 0)