From owner-freebsd-arch Sun Jan 6 22:16:37 2002 Delivered-To: freebsd-arch@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 2961337B400 for ; Sun, 6 Jan 2002 22:16:32 -0800 (PST) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id RAA00578; Mon, 7 Jan 2002 17:16:05 +1100 Date: Mon, 7 Jan 2002 17:16:42 +1100 (EST) From: Bruce Evans X-X-Sender: To: Peter Wemm Cc: Archie Cobbs , Alfred Perlstein , Dan Eischen , Subject: Re: Request for review: getcontext, setcontext, etc In-Reply-To: <20020106232937.9F87D38CC@overcee.netplex.com.au> Message-ID: <20020107164848.J468-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 #include #include #include 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