Bug 22286

Summary: siglongjmp does not properly restore the signal stack
Product: Base System Reporter: Bram <Bram>
Component: binAssignee: Marcel Moolenaar <marcel>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Bram 2000-10-25 10:30:01 UTC
When using siglongjmp() to jump from a signal handler back to the main code, while the signal function uses the signal stack (defined with sigaltstack()), this works only once.  The next time the signal handler is called the program crashes, apparently because the signal stack is not operating.  Setting the signal stack again (with sigaltstack()) works around the problem.  The same code works fine on other systems that have sigaltstack().

Fix: 

No known solution
How-To-Repeat: Compile and run the program below.  Result:
	In while
	Signal recieved!
	In while
	Illegal instruction(core dumped)

Now define "WORKAROUND" and do it again.  Result:
	In while
	Signal recieved!
	In while
	Signal recieved!
	In while
	Signal recieved!
	etc.

#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>

/* #define WORKAROUND */

sigjmp_buf	env;
stack_t		ss;
struct sigaction sa;

void foo(void)
{
    int	a[32768];

    foo();	/* recursively call ourselves until out of stack space */
}

void sighandler(int sig)
{
    siglongjmp(env, 100);
}

main() {

    if ((ss.ss_sp = malloc(SIGSTKSZ)) == NULL)
	exit(1);

    ss.ss_size = SIGSTKSZ;
    ss.ss_flags = 0;
    if (sigaltstack(&ss,(stack_t *)0) < 0) {
	perror("sigaltstack");
	exit(1);
    }

    sa.sa_handler = sighandler;
    sa.sa_flags = SA_ONSTACK;
    if (sigaction(SIGSEGV, &sa, 0) < 0) {
	perror("sigaction");
	exit(1);
    }

    while (1) {
	puts("In while");
	if (!sigsetjmp(env, 1))
	    foo();
	else
	{
	    puts("Signal recieved!");
#ifdef WORKAROUND
	    if (sigaltstack(&ss, (stack_t *)0) < 0) {
		perror("sigaltstack");
		exit(1);
	    }
#endif
	}
    }
}
Comment 1 David E. O'Brien freebsd_committer freebsd_triage 2000-11-11 02:39:35 UTC
Responsible Changed
From-To: freebsd-bugs->marcel

Marcel said he would take a look at it and get it to the right person if he 
can't fix it.
Comment 2 Marcel Moolenaar freebsd_committer freebsd_triage 2001-09-08 20:26:03 UTC
State Changed
From-To: open->closed

This has been fixed more than 9 months ago. The PR stayed open while 
I was focusing on other things. Ah well... :-)