From nobody@FreeBSD.ORG  Wed Oct 25 02:29:49 2000
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 2867637B479; Wed, 25 Oct 2000 02:29:49 -0700 (PDT)
Message-Id: <20001025092949.2867637B479@hub.freebsd.org>
Date: Wed, 25 Oct 2000 02:29:49 -0700 (PDT)
From: Bram@vim.org
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@FreeBSD.org
Subject: siglongjmp does not properly restore the signal stack
X-Send-Pr-Version: www-1.0

>Number:         22286
>Category:       bin
>Synopsis:       siglongjmp does not properly restore the signal stack
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    marcel
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 25 02:30:01 PDT 2000
>Closed-Date:    Sat Sep 8 12:26:03 PDT 2001
>Last-Modified:  Sat Sep 08 12:27:21 PDT 2001
>Originator:     Bram Moolenaar
>Release:        4.0 release
>Organization:
>Environment:
FreeBSD masaka.moolenaar.net 4.0-RELEASE FreeBSD 4.0-RELEASE #2: Mon Oct 16 18:20:45 CEST 2000     mool@masaka.moolenaar.net:/usr/src/sys/compile/MASAKA  i386

>Description:
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().
>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
	}
    }
}

>Fix:
No known solution

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->marcel 
Responsible-Changed-By: obrien 
Responsible-Changed-When: Fri Nov 10 18:39:35 PST 2000 
Responsible-Changed-Why:  
Marcel said he would take a look at it and get it to the right person if he 
can't fix it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=22286 
State-Changed-From-To: open->closed 
State-Changed-By: marcel 
State-Changed-When: Sat Sep 8 12:26:03 PDT 2001 
State-Changed-Why:  
This has been fixed more than 9 months ago. The PR stayed open while 
I was focusing on other things. Ah well... :-) 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=22286 
>Unformatted:
