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
 */

Reply via email to