From owner-freebsd-current Wed Aug 26 06:43:39 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id GAA01077 for freebsd-current-outgoing; Wed, 26 Aug 1998 06:43:39 -0700 (PDT) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from gilgamesch.bik-gmbh.de (gilgamesch.bik-gmbh.de [194.233.237.91]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id GAA01044 for ; Wed, 26 Aug 1998 06:43:31 -0700 (PDT) (envelope-from cracauer@gilgamesch.bik-gmbh.de) Received: (from cracauer@localhost) by gilgamesch.bik-gmbh.de (8.8.8/8.7.3) id PAA22425; Wed, 26 Aug 1998 15:42:41 +0200 (MET DST) Message-ID: <19980826154241.A22184@cons.org> Date: Wed, 26 Aug 1998 15:42:41 +0200 From: Martin Cracauer To: Bruce Evans , current@FreeBSD.ORG, luoqi@watermarkgroup.com, shocking@prth.pgs.com Subject: Re: Floating Point Exceptions, signal handlers & subsequent ops References: <199808252351.JAA32306@godzilla.zeta.org.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.93.1i In-Reply-To: <199808252351.JAA32306@godzilla.zeta.org.au>; from Bruce Evans on Wed, Aug 26, 1998 at 09:51:57AM +1000 Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In <199808252351.JAA32306@godzilla.zeta.org.au>, Bruce Evans wrote: > 2) if the SIGFPE was for an FP operation, then the FP operatation will be > restarted. The kernel has cleared the trap-pending flag before delivering > the SIGFPE to the application, and on i386's traps are delivered to the > kernel on the the first non-control FP operation after the one that > caused the exception, so it is certain that the restarted FP operation > won't trap; it may cause an exception which will be delivered to the > kernel on the next non-control FP operation. I'm not able to reproduce this behaviour. I wrote a short test program that runs like this: Trying to trigger a FPE and see if FP still works afterwards. First round - FPE-causing operation and then a non-exception operation. Operation caused exception -> right. Next operation after fpe worked and gave correct result -> right. Second round - directly following FPE-causing operations. First operation caused exception -> right. Second operation caused exception -> right >From your description, I would expect the next FP operating after a caught FPE exception to fail. Either by issuing a wrong result, by not troughing FPE where it should or throughing one where it shouldn't. Here's what I do. Don't compile this with optimization, my actions against it aren't sufficient. #include #include #include #include volatile sig_atomic_t fpe_was_here = 0; static void handler(int s) { fpe_was_here++; write(2, "sig\n", 4); } /* Don't use printf, it uses floating point */ #define TO_STDERR(arg) write(2, arg, sizeof(arg)) int main(void) { double f0; double f2; double f4; double f8; double res; double old_res; int old_fpe_was_here; double killopt = 0.0; /* Prevent optimization */ f0 = atof("0.0"); f2 = atof("2.0"); f4 = atof("4.0"); f8 = atof("8.0"); TO_STDERR("Trying to trigger a FPE and see if FP still works afterwards.\n"); TO_STDERR("\nFirst round - FPE-causing operation and then a non-exception " "operation.\n"); signal(SIGFPE, handler); res = f2 / f0; killopt += res; if (fpe_was_here) { TO_STDERR("Operation caused exception -> right.\n"); fpe_was_here--; } else { TO_STDERR("Operation works fine -> wrong.\n"); } if (fpe_was_here) { TO_STDERR("Aehm, what?\n"); exit(1); } res = f4 + f8; killopt += res; if (fpe_was_here) { TO_STDERR("Next normal operation caused exception -> wrong.\n"); fpe_was_here--; } if (res != 12.0) { TO_STDERR("Next operation gave wrong result :-(\n"); } else { TO_STDERR("Next operation after fpe worked and gave correct result " "-> right.\n"); } TO_STDERR("\nSecond round - directly following FPE-causing operations.\n"); old_res = f2 / f0; /* Don't do a any output here to keep Schroedinger happy */ old_fpe_was_here = fpe_was_here; fpe_was_here--; res = f2 / f0; killopt += old_res; killopt += res; if (old_fpe_was_here) { TO_STDERR("First operation caused exception -> right.\n"); old_fpe_was_here--; } else { TO_STDERR("First operation works fine -> wrong.\n"); } if (old_fpe_was_here) { TO_STDERR("Aehm, what?\n"); exit(1); } if (fpe_was_here) { TO_STDERR("Second operation caused exception -> right\n"); fpe_was_here--; } else { TO_STDERR("Second operation works fine -> wrong\n"); } if (fpe_was_here) { TO_STDERR("Aehm, what?\n"); exit(1); } fprintf(stderr,"For the record and against the optimizer: %g\n", killopt); return 0; } -- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Martin Cracauer http://www.cons.org/cracauer BSD User Group Hamburg, Germany http://www.bsdhh.org/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message