Paul Eggert wrote:
> > Now, you are arguing "let's ignore whether programs use nested functions".
>
> Not at all. All I'm saying is, stack-overflow handlers shouldn't call
> via pointers to nested functions.
>
> There are already several restrictions on stack-overflow handlers; for
> example, you can't call 'exit'. A restriction against calling via
> pointers to nested functions is just another restriction - one that's
> easier to comply with than the 'exit' restriction, in my experience.
I agree that these handlers are _usually_ small and don't have nested
functions. But a restriction is a restriction, and should be documented
as such. Find attached a proposed patch.
> If stack-overflow handlers absolutely can't live without calling via
> pointers to nested functions, one can work around the problem by
> compiling with gcc -fno-trampolines.
No, "gcc -fno-trampolines" doesn't get rid of the need to have an executable
stack. In the attached sample code gcc-closure.c, GCC 11.1 produces identical
code with "gcc -fno-trampolines" than with "gcc -ftrampolines".
> > being close to POSIX would mean to use SIGSTKSZ for the allocation
> > of an alternate stack, most likely through malloc.
>
> That would also be a reasonable change to the test cases. I didn't do
> that, partly because I thought it simpler just to allocate an enormous
> alternate signal stack, partly because I wasn't yet entirely clear on
> exactly when malloc is bad for allocating alternate signal stacks so I
> wanted to avoid malloc entirely. But if you'd prefer that the test cases
> use malloc I can rewrite them to do that.
Thanks for the offer. I think we should get clarity first, regarding which
of the three approaches (static allocation, malloc, alloca) is preferrable.
I'll try to write documentation for it.
Bruno
diff --git a/lib/c-stack.h b/lib/c-stack.h
index 56d74f1..8bf773c 100644
--- a/lib/c-stack.h
+++ b/lib/c-stack.h
@@ -34,8 +34,10 @@
A null ACTION acts like an action that does nothing.
ACTION must be async-signal-safe. ACTION together with its callees
- must not require more than 64 KiB of stack space. Also,
- ACTION should not call longjmp, because this implementation does
+ must not require more than 64 KiB of stack space. ACTION must not create
+ nested functions <https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>,
+ because this implementation does not guarantee an executable stack.
+ Also, ACTION should not call longjmp, because this implementation does
not guarantee that it is safe to return to the original stack.
This function may install a handler for the SIGSEGV signal or for the SIGBUS
/* Test whether a lexical closure created by GCC requires an executable stack.
Compile this file with
cross <target> gcc -O2 -S -fomit-frame-pointer gcc-closure.c
*/
extern int callback (void (*) (void));
int foo (void)
{
int x = 0;
void increment_x (void) { x++; }
callback (increment_x);
return x;
}
/* Result:
i386 yes
x86_64 yes
m68k yes
mips yes
mips64 yes
sparc yes
sparc64 yes
alpha yes
hppa ?
hppa64 ?
arm yes
arm64 yes
powerpc no
powerpc64 no
powerpc64-elfv2 no
ia64 no
s390 yes
s390x yes
riscv32 yes
riscv64 yes
*/