Date: Mon, 7 Jan 2002 17:16:42 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: Peter Wemm <peter@wemm.org> Cc: Archie Cobbs <archie@dellroad.org>, Alfred Perlstein <bright@mu.org>, Dan Eischen <eischen@vigrid.com>, <arch@FreeBSD.ORG> Subject: Re: Request for review: getcontext, setcontext, etc Message-ID: <20020107164848.J468-100000@gamplex.bde.org> In-Reply-To: <20020106232937.9F87D38CC@overcee.netplex.com.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 6 Jan 2002, Peter Wemm wrote: > The context argument passed in to signal handlers should be able to be used > with setcontext() to return from the signal handler as an alternative to > sigreturn(). Doing it in libc wont work there because you race with > restoring the signal mask before you've finished setting the application > state. The i386 siglongjmp() gets this wrong despite using a syscall (sigprocmask): %%% #define _POSIX_SOURCE 1 #include <setjmp.h> #include <signal.h> #include <string.h> #include <unistd.h> sigjmp_buf jb; static void catch(int sig) { char buf[4 * 1024 * 1024]; /* Large to use up stack fast. */ sigset_t omask; sigprocmask(SIG_BLOCK, NULL, &omask); sprintf(buf, "caught signal %d @ %p; signal mask %#x\n", sig, (void *)&buf[0], *(unsigned *)&omask); /* XXX */ write(1, buf, strlen(buf)); kill(getpid(), sig); /* Simulate a race. */ sprintf(buf, "signals apparently masked correctly before siglongjmp\n"); write(1, buf, strlen(buf)); siglongjmp(jb, 1); } int main(void) { struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = catch; sigaction(SIGUSR1, &sa, NULL); if (sigsetjmp(jb, 1) == 0) kill(getpid(), SIGUSR1); return (0); } %%% Myabe this can be fixed by restoring %esp before calling sigprocmask; otherwise siglongjmp needs to use sigreturn (or the corresponding syscall that restores the whole ucontext). > Also, I noticed that the i386 patch doesn't save FP state (!) which is > one of the primary reasons for get/setcontext(). I'm not sure if this > can be efficiently done since this user-level function will not know if > the current context has touched the FPU yet.. I think doing it in userland basically forces you to do physical FPU accesses using fnsave/frstor (and something different for the SSE case?). The case where a syscall would be most efficient (when the FPU is not used) will be especially inefficient since it will have to trap to the kernel anyway to access the state. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020107164848.J468-100000>