• R
    redesign sigsetjmp so that signal mask is restored after longjmp · 583e5512
    Rich Felker 提交于
    the conventional way to implement sigsetjmp is to save the signal mask
    then tail-call to setjmp; siglongjmp then restores the signal mask and
    calls longjmp. the problem with this approach is that a signal already
    pending, or arriving between unmasking of signals and restoration of
    the saved stack pointer, will have its signal handler run on the stack
    that was active before siglongjmp was called. this can lead to
    unbounded stack usage when siglongjmp is used to leave a signal
    handler.
    
    in the new design, sigsetjmp saves its own return address inside the
    extended part of the sigjmp_buf (outside the __jmp_buf part used by
    setjmp) then calls setjmp to save a jmp_buf inside its own execution.
    it then tail-calls to __sigsetjmp_tail, which uses the return value of
    setjmp to determine whether to save the current signal mask or restore
    a previously-saved mask.
    
    as an added bonus, this design makes it so that siglongjmp and longjmp
    are identical. this is useful because the __longjmp_chk function we
    need to add for ABI-compatibility assumes siglongjmp and longjmp are
    the same, but for different reasons -- it was designed assuming either
    can access a flag just past the __jmp_buf indicating whether the
    signal masked was saved, and act on that flag. however, early versions
    of musl did not have space past the __jmp_buf for the non-sigjmp_buf
    version of jmp_buf, so our setjmp cannot store such a flag without
    risking clobbering memory on (very) old binaries.
    583e5512
sigsetjmp.s 336 字节