Subject: port-i386/1832: FPE bug in i386 1.1
To: None <gnats-bugs@gnats.netbsd.org>
From: Neil J. McRae <neil@demon.net>
List: netbsd-bugs
Date: 12/12/1995 12:37:39
>Number: 1832
>Category: port-i386
>Synopsis: NetBSD 1.1 has severe FPE bugs.
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Dec 12 07:50:00 1995
>Last-Modified:
>Originator: Neil J. McRae
>Organization:
Neil J. McRae. Demon Internet
neil@demon.net
NetBSD: Free the daemon in your <a href="http://www.NetBSD.ORG/">computer!</a>
>Release: NetBSD 1.1
>Environment:
System: NetBSD NetBSD.noc.demon.net 1.1 NetBSD 1.1 (NETBSD) #4: Fri Dec 1 16:32:30 GMT 1995 neil@NetBSD.corp.demon.net:/usr/src/sys/arch/sparc/compile/NETBSD sparc
>Description:
The FPE code in NetBSD 1.1 has several bugs that cause programs that use
it to coreth dumpeth.
>How-To-Repeat:
/*
* attempt to provoke the FPE bug in NetBSD 1.1
* We for lots of little children which all do FP work. The NPX doesn't
* seem to be correctly reset for some of the children so we blow up with
* what seems to be FP stack overflow ?
*
* Compile with -DFLOAT to enable the test.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
/*
* gcc 2.4.5 doesn't seem to understand sig_atomic_t properly.
* On a machine with FPU disabled, this will cause the program to hang
* after a while. This does not invalidate the test.
*/
sig_atomic_t count = 0;
#define MAX 5
void handler()
{
int pid, status;
while ((pid = wait(&status)) > 0) {
count--;
if (WIFSIGNALED(status)) {
printf("Child died on signal %d\n", WTERMSIG(status));
exit(1);
}
}
/* if (pid < 0)
perror("wait"); */
}
void xhandler()
{
printf("alarm clock, count = %d\n", count);
alarm(5); handler();
}
int do_one()
{
int pid;
if ((pid = fork()) > 0) {
/* parent */
count++;
printf("parent: %d children\n", count);
}
else {
int i;
#ifdef FLOAT
/* child */
float answer;
answer = 0.5 * 23;
printf("child %d: answer = %f\n", getpid(), answer);
#endif
exit(0);
}
return 0;
}
int main (int argc, char *argv[])
{
struct sigaction action;
action.sa_handler = handler;
action.sa_mask = 0;
action.sa_flags = SA_NOCLDSTOP;
sigaction(SIGCHLD, &action, 0);
action.sa_handler = xhandler;
sigaction(SIGALRM, &action, 0);
alarm(5);
while (1) {
/* printf("again\n"); */
while (count < MAX)
do_one();
pause();
}
}
>Fix:
Workaround: Disable the FPU (ewww) but this makes X almost useless!
*** /usr/src/sys/arch/i386/isa/npx.c Sat Oct 14 02:58:53 1995
--- /sys/arch/i386/isa/npx.c Fri Nov 24 11:13:06 1995
***************
*** 221,226 ****
--- 221,230 ----
npx_type = NPX_BROKEN;
ia->ia_irq = IRQUNK;
}
+ #ifdef IGNOREFPU
+ npx_type = NPX_BROKEN;
+ ia->ia_irq = IRQUNK;
+ #endif
return 1;
}
}
>Audit-Trail:
>Unformatted: