kern/131597: [kernel] c++ exceptions very slow on FreeBSD 7.1/amd64

Bruce Evans brde at optusnet.com.au
Tue Sep 14 15:18:23 UTC 2010


On Tue, 14 Sep 2010, Tijl Coosemans wrote:

> On Thu, Jul 08, 2010 at 11:29:50AM -0400, John Baldwin wrote:
> > ...longjmp(3) isn't safe in a signal context...
>
> POSIX says it's supposed to be safe:
>
>   "As it bypasses the usual function call and return mechanisms,
>   longjmp() shall execute correctly in contexts of interrupts, signals,
>   and any of their associated functions. However, if longjmp() is
>   invoked from a nested signal handler (that is, from a function
>   invoked as a result of a signal raised during the handling of another
>   signal), the behavior is undefined."

It cannot be really safe.  It can only execute correctly (where the
definition of "correctly" must not require much more than restoring the
context saved by setjmp().  Consider a signal interrupting almost any
library function that acts on global storage.  Only return from the
signal handler (after not clobbering the global storage acted on by the
function) can let the function complete correctly.

POSIX also says:
23731              All accessible objects have values, and all other components of the abstract machine have state
23732              (for example, floating-point status flags and open files), as of the time longjmp( ) was called,
23733              except that the values of objects of automatic storage duration are unspecified if they meet all
23734              the following conditions:

I don't really understand unwinding, but this seems to forbid significant
unwinding.  This also expicitly requires broken behaviour for the floating
point state.  Keeping the floating point status flags at the time of the
longjmp() is good in general (so that the flags accumulate), but not when
the longjmp() is from a signal handler since signal handlers should get a
clean FP state.  Keeping other parts of the FP environment at the time of
the longjmp() is not so good in general, and worse for longjmp() from signal
handlers.  FreeBSD is supposed to keep the FP status flags at the time of
the longjmp() and restore the FP control flags at the time of the setjmp(),
but gets this wrong in more than half of the 24 cases (24 cases = 2 arches
times 3 longjmp()s (also _longjmp() and siglongjmp()) times 4 sets of flags
(mxcsr control/status and i387-environment control/status); only 1 of the
6 longjmp files has been updated to understand mxcsr, and it still uses the
old method of clearing the i386 status flags.

Bruce


More information about the freebsd-bugs mailing list