setjmp/longjmp & signal handlers bug

Christopher Faylor cgf-no-personal-reply-please@cygwin.com
Tue Oct 12 00:10:00 GMT 2004


On Mon, Oct 11, 2004 at 06:00:07PM -0500, Brian Ford wrote:
>$ uname -a
>CYGWIN_NT-5.1 fordpc 1.5.12(0.116/4/2) 2004-10-11 16:50 i686 unknown
>unknown Cygwin
>
>$ cat longjmp_signal.c
>#include <setjmp.h>
>#include <signal.h>
>#include <stdio.h>
>#include <unistd.h>
>
>static jmp_buf env;
>
>void
>handler(int sig)
>{
>    longjmp(env, 1);
>    puts("longjmp failed");
>    exit(-2);
>}
>
>int
>main(void)
>{
>    int i;
>
>    for (i = 0; i < 2; i++)
>    {
>        volatile char *p = NULL;
>
>        signal(SIGSEGV, handler);
>
>        if (setjmp(env) == 0)
>        {
>            *p;
>            puts("SEGV failed");
>            exit(-1);
>        }
>        else
>            printf("Partial success: %d\n", i);
>    }
>
>    puts("PASS");
>
>    return 0;
>}
>
>$ gcc -g -O2 longjmp_signal.c -o longjmp_signal.exe
>
>$ ./longjmp_signal.exe
>Partial success: 0
>
>$ echo $?
>5
>
>I would expect additional output:
>Partial success: 1
>PASS
>
>and a 0 return status?
>
>Thanks.

Did you try this on linux?  You get roughly the same behavior.  The SEGV
signal is blocked while it's in the signal handler so if you jump out of
the signal handler, it's still blocked.

Where cygwin and linux differ is in the exit value.  linux exits with
the correct value after figuring out that it can do nothing but exit.
cygwin ends up exiting from the windows exception handling code, which
knows nothing about UNIX exit codes.  Fixing that is tricky because the
code has to return and not just exit because the exception may have been
fixed by a potential signal handler and you can't just assume that the
program should exit.

cgf

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list