This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fwd: What can a signal handler do with SIGSTKSZ?
- From: Zack Weinberg <zackw at panix dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 11 Jan 2019 14:34:30 -0500
- Subject: Fwd: What can a signal handler do with SIGSTKSZ?
- References: <e4215c6e-e8a4-a9b6-d88f-3c54e262711a@redhat.com> <CAKCAbMiCaBst_ofjKkH3Ck1CoOV86wPKv3QSkC89XW_zu=1BLA@mail.gmail.com>
[accidental off-list reply, sorry about that]
On Fri, Jan 11, 2019 at 12:44 PM Carlos O'Donell <carlos@redhat.com> wrote:
> The implementation only guarantees that a signal handler can
> manipulate a reasonable amount of local variables (no more than
> 2 KiB worth), and can read and write to memory, carry out atomic
> operations, and call simple C library functions that do similar
> memory and simple string operations e.g. memcpy, memset, strcmp,
> strcpy. The amount of signal stack allocated for SIGSTKSZ is not
> sufficient to call complex signal-safe functions e.g. fork, _exit,
> abort, nor any that can be canceled (requires enough stack for
> cancellation). Any other operations or function calls in the
> signal handler should be evaluated for runtime stack usage and
> additional stack beyond SIGSTKSZ should be allocated.
With my application programmer hat on, my expectation is that SIGSTKSZ
is supposed to be a _reasonable default_ amount of stack space, not a
minimum. MINSIGSTKSZ is the minimum. And this is too restrictive
even as the definition of the minimum. The minimum (MINSIGSTKSZ)
should include adequate space to call _any_ async-signal-safe
function, most definitely including `_exit` and `abort`, provided I am
cautious regarding local variables in the signal handler.
In SIGSTKSZ space I expect to be able to do arbitrary computation and
call arbitrary library functions (provided that the signal is
delivered synchronously) and to not have to worry about the amount of
space consumed by stack variables or procedure calls. The only things
I _wouldn't_ feel safe doing are `alloca` and input-bounded recursion.
Having said that, if I put my systems programmer hat back on and look
at the actual values for these constants in the existing library...
[sysdeps/unix/sysv/linux/...]
bits/sigstack.h MINSIGSTKSZ 2048
alpha/bits/sigstack.h MINSIGSTKSZ 4096
powerpc/bits/sigstack.h MINSIGSTKSZ 4096
sparc/bits/sigstack.h MINSIGSTKSZ 4096
aarch64/bits/sigstack.h MINSIGSTKSZ 5120
ia64/bits/sigstack.h MINSIGSTKSZ 131027
bits/sigstack.h SIGSTKSZ 8192
aarch64/bits/sigstack.h SIGSTKSZ 16384
alpha/bits/sigstack.h SIGSTKSZ 16384
powerpc/bits/sigstack.h SIGSTKSZ 16384
sparc/bits/sigstack.h SIGSTKSZ 16384
ia64/bits/sigstack.h SIGSTKSZ 262144
... I reach the conclusion that they are all way too small, except
ia64, and the generic bits/sigstack.h (currently used only by Hurd)
has the right idea:
#define MINSIGSTKSZ 8192
#define SIGSTKSZ (MINSIGSTKSZ + 32768)
Maybe bump 32768 up to 131072 to account for bloat since 1998.
Now, if 8192 bytes is not enough to call some async-signal-safe
functions, that's another problem and one I would like to see
addressed by making the unwind library more space-efficient or
something along those lines.
zw