Hi,
A signal handler is invoked with incorrect setting of the FP control word
if precision is set different than _FPU_EXTENDED on linux 2.2.x kernel on
x86. A siglongjmp() will further *pollute* the process with the incorrect
control word.
A pthread application being (pthread) signalled while waiting in a
pthread_cond_timedwait() is exposed to this bug (sample program available
upon request).
This bug is very annoying if the application requires 64-bit FP precision
and is exposed to the bug, e.g., uses pthreads.
Below is a sample program demonstrating the bug.
Since I don't read this mailing list too often, please cc me any reponse.
Enjoy!
hob
---------------------------------
/*
* Author: H. Bugge, Scali AS, May 2000
*
* This program demonstrates that the Linux/x86 signal system invokes
* the signal catching routine with an incorrect FP control word.
* This is extreemly annoying if 64-bit precision is required, and the
* application uses signals, e.g. pthreads.
*
* To compile&run:
*
* gcc fpucw.c;a.out
*/
#include <assert.h>
#include <fpu_control.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
typedef void (*sighandler_t)(int);
jmp_buf env;
char *precision_mnemonic[] = {"SINGLE", "BAD VALUE", "DOUBLE", "EXTENDED" };
void print_fp_precision(char *str, int expected_prec) {
int actual_prec;
fpu_control_t cw;
_FPU_GETCW(cw);
actual_prec = cw & _FPU_EXTENDED;
printf("%-20s: %10s. %s\n",
str, precision_mnemonic[actual_prec >> 8],
(actual_prec == expected_prec ? "OK" : "ERROR")
);
}
sighandler_t catcher(int sig) {
print_fp_precision("Before siglongjmp", _FPU_DOUBLE);
siglongjmp(env, 1);
}
int main() {
fpu_control_t cw;
print_fp_precision("Beginning of main()", _FPU_EXTENDED);
/* set 64-bit FP precision */
_FPU_GETCW(cw);
cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(cw);
print_fp_precision("After _FP_SETCW", _FPU_DOUBLE);
signal(SIGUSR2, (sighandler_t)catcher);
print_fp_precision("Before sigsetjmp", _FPU_DOUBLE);
if (sigsetjmp(env, 1) == 0) {
print_fp_precision("After sigsetjmp", _FPU_DOUBLE);
kill(getpid(), SIGUSR2);
assert(0);
} else {
print_fp_precision("After longjmp", _FPU_DOUBLE);
}
return(0);
}
-- Håkon Bugge; VP Product Development; Scali AS; mailto:hob@scali.no; http://www.scali.com; fax: +47 22 62 89 51; Voice: +47 22 62 89 50; Cellular (Europe): +47 924 84 514; Visiting Addr: Olaf Helsets vei 6, Bogerud, N-0621 Oslo, Norway; Mail Addr: Scali AS, Postboks 70, Bogerud, N-0621 Oslo, Norway;- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:22 EST