Date: Thu, 3 Feb 1994 15:50:59 +0500 From: ronis AT onsager (David Ronis) To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: DJGPP Floating point execeptions hang Desqview I run Desqview/X on a 50MHz 486DX with 16Meg of ram and lots of hard disk space and Desqview on a 20MHz Everex Step/20 with a 387 and 16Meg. There was a bug in the pre 1.11 versions of djgpp that lead to my machines locking up if I ran a djgpp compiled program that generated a floating-point exception inside of DV(/X) (outside of DV(/X) I simply get the standard stack trace). The problem apparently was that go32 wasn't saving/restoring something critical to DV(/X). I was on the beta test for 1.11 and at least by the beta7 version the bug was fixed. However, the bug is back in the release copies (in 1.11, 1.11.maint1 and 1.11.maint2). I'm pretty sure that the problem is with go32, since running the offending program with the beta7 version doesn't lead to a lockup (only the stack trace). Unfortunately, I didn't save the sources for beta7 and so haven't a clue as to what has changed. Any help would be appreciated. I've attached a simple test program that can be used to generate several kinds of floating-point exceptions. On the 486, I compile it as: gcc -O2 -m486 -o float float.c -lm followed by aout2exe float Thanks in advance. David Ronis =============================Cut Here====================================== #include #include #include void usage(void); void exptest(int,char **); void divtest(int,char**); void sqrttest(int,char**); void sinhtest(int,char**); void multest(int,char**); void undertest(int,char**); enum tests { EXPTEST, DIVTEST, SQRTTEST, SINHTEST, MULTEST, UNDERTEST } test; main(int argc,char **argv) { if(argc<2)usage(); argc-=2; argv+=2; switch(atoi(argv[-1])){ case EXPTEST : exptest(argc,argv); break; case DIVTEST : divtest(argc,argv); break; case SQRTTEST : sqrttest(argc,argv); break; case SINHTEST : sinhtest(argc,argv); break; case MULTEST : case UNDERTEST : multest(argc,argv); break; default : usage(); } exit(0); } void exptest(int argc,char **argv) /* Exponental Overflow */ { double x=1.0,y; int count=100; switch(argc){ case 2 : count=atoi(argv[1]); case 1 : x=atof(argv[0]); } printf("Exptest: count=%d; x=%lg\n",count,x); fflush(stdout); while(count-->0){ printf("exp(%lg)=%lg\n",x,y=exp(x)); x=y; fflush(stdout); } return; } void divtest(int argc,char **argv) /* Division by zero */ { double x=0.0; printf("Divtest: x=%lg; 1/x=%lg\n",x,1.0/x); fflush(stdout); return; } void sqrttest(int argc,char **argv) /* Square-root of a negative number */ { double x=-1.0; if(argc>0)x=atof(argv[0]); printf("Sqrttest: sqrt(%lg)=%lg\n",x,sqrt(x)); fflush(stdout); return; } void sinhtest(int argc,char **argv) /* Sinh overflow */ { double x=1.0,y; int count=100; switch(argc){ case 2 : count=atoi(argv[1]); case 1 : x=atof(argv[0]); } printf("sinhtest: count=%d; x[0]=%lg\n",count,x); fflush(stdout); while(count-->0){ printf("sinh(%lg)=%lg\n",x,y=sinh(x)); x=y; fflush(stdout); } return; } void multest(int argc,char **argv) /* Multiplication Over/Under flow*/ { double x=1.0,y; int count=100; switch(argc){ case 2 : count=atoi(argv[1]); case 1 : x=atof(argv[0]); } printf("Multest: count=%d; x=%lg\n",count,x); fflush(stdout); while(count-->0){ printf("x=%lg x*=x = %lg\n",x,y=x*x); x=y; fflush(stdout); } return; } void usage() { fprintf(stderr,"usage: float test_number [starting value [count]]\nwhere\n\n"); fprintf(stderr,"\t\t%d Exponential overflow\n",EXPTEST); fprintf(stderr,"\t\t%d Division by zero\n",DIVTEST); fprintf(stderr,"\t\t%d Sqrt of -1.0\n",SQRTTEST); fprintf(stderr,"\t\t%d Sinh overflow\n",SINHTEST); fprintf(stderr,"\t\t%d Multiplication overflow\n",MULTEST); fprintf(stderr,"\t\t%d Underflow\n",UNDERTEST); exit(1); }