Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Jan 2002 07:58:26 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Dan Eischen <eischen@vigrid.com>
Cc:        Peter Wemm <peter@wemm.org>, Archie Cobbs <archie@dellroad.org>, Alfred Perlstein <bright@mu.org>, <arch@FreeBSD.ORG>
Subject:   Re: Request for review: getcontext, setcontext, etc
Message-ID:  <20020108071957.I2280-100000@gamplex.bde.org>
In-Reply-To: <3C396F9F.A53049E4@vigrid.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 7 Jan 2002, Dan Eischen wrote:

> Bruce Evans wrote:
> >
> > 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):
> > [... example program deleted]

BTW, the program shows another bug when compiled with -pthread.  It crashes
with a SIGSEGV in _thread_sig_wrapper(), apparently due to stack growing
problems.  Reducing the size of buf[] from 4MB to 1MB fixes this.

> I don't really see how having the *context() or *jmp() routines be
> a syscall helps.  You still have to protect the accesses to the
> jmp_buf or ucontext for race conditions regardless of whether these
> functions are syscalls or not.  There's a few instructions to be
> executed after leaving the kernel via a system call anyways, right?
> You could always get preempted there and have another signal be
> delivered.

You are back in the context of the caller of setjmp() by then.  But I
think that that context, except for the signal mask, can be duplicated
well enough by careful context switching in userland.  The jmp_buf must
be "on" both the new and the old stack if it is on a stack at all,
since it must remain valid until setjmp() returns.  So we can leave
things in jmp_buf (but we shouldn't modify jmp_buf since we might be
preempted by another signal handler that uses it to do a more final
longjmp (we could avoid preemption by blocking _all_ signals, but that
would require even more syscalls)).

> > > 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?).
>
> We do this in libc_r right now.  When a signal is caught, we use fnsave
> to save the FP regs to the ucontext area

But this tends to give the trap to load the state from kernel memory so
that userland can save it back to user memory.  The trap may be more
efficient than a syscall, but that's partly because syscalls are more
pessimized.  A single syscall to save the entire ucontext may be more
efficient.

> (knowing the kernel doesn't
> do it for us -- shouldn't it be saving the FP regs?).  We remember

Yes.  Use of FP in signal handlers currently corrupts the FP state of
whatever was interrupted (on i386's).

> that the threads context has FP regs saved in this case and use
> frstor when it is resumed.  Threads interrupted by signals are the
> only case (for i386) that FP regs are saved and restored.

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?20020108071957.I2280-100000>