Date: Wed, 15 Sep 2010 00:10:11 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Tijl Coosemans <tijl@coosemans.org> Cc: freebsd-bugs@FreeBSD.org Subject: Re: kern/131597: [kernel] c++ exceptions very slow on FreeBSD 7.1/amd64 Message-ID: <20100914225327.B825@delplex.bde.org> In-Reply-To: <201009140940.o8E9e3dH040847@freefall.freebsd.org> References: <201009140940.o8E9e3dH040847@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100914225327.B825>