Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Oct 2000 02:29:49 -0700 (PDT)
From:      Bram@vim.org
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/22286: siglongjmp does not properly restore the signal stack
Message-ID:  <20001025092949.2867637B479@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         22286
>Category:       bin
>Synopsis:       siglongjmp does not properly restore the signal stack
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 25 02:30:01 PDT 2000
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001025092949.2867637B479>