Mail Archives: djgpp/1996/05/23/21:29:08
On Thu, 16 May 1996, Charles Sandmann wrote:
> I can't say for sure, but NT may be delaying you seeing the interrupt,
> or maybe there is a bug in the signal code in this case as far as the
> saved register information. It certainly doesn't look right. Things
> to try:
> 1) while in your error catcher routine, look at the values in the
> __djgpp_exception_state structure (sys/exceptn.h ?) and look in
> the source directory src/libc/go32/dpmiexcp.c for hints.
> 2) you might try the assembly level floating point store info routine to
> get a copy of the FPU state for examination - I think it contains
> the EIP of the faulting instruction.
> Good luck, and let us know what you find.
>
I have a solution now. It was suggestion #2 that turned out to be the
vital clue, and having the source code for fsdb.
fsdb not only catches an FPE, but knows what instruction caused the
error. Purusing the source code showed me how to get the FPU state and
find the eip of the offending instruction. While I still can't get the
entire stack trace, just knowing which line of code caused the error is
of tremendous help. Thanks for the tips!
Sample code follows.
Jeff
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
typedef unsigned long word32;
typedef unsigned short word16;
typedef unsigned char word8;
typedef signed long int32;
typedef signed short int16;
typedef signed char int8;
typedef struct {
word16 sig0;
word16 sig1;
word16 sig2;
word16 sig3;
word16 exponent:15;
word16 sign:1;
} NPXREG;
typedef struct {
word32 control;
word32 status;
word32 tag;
word32 eip;
word32 cs;
word32 dataptr;
word32 datasel;
NPXREG reg[8];
} NPX;
static NPX npx ;
/* Store the contents of the NPX in the global variable `npx'. */
static inline void
save_npx (void)
{
asm ("inb $0xa0, %%al
testb $0x20, %%al
jz 1f
xorl %%al, %%al
outb %%al, $0xf0
movb $0x20, %%al
outb %%al, $0xa0
outb %%al, $0x20
1:
fnsave %0
fwait"
: "=m" (npx)
: /* No input */
: "%eax");
}
void ErrorCatcher(int *reglist)
{
save_npx() ;
fprintf(stderr, "Floating point error:\n") ;
fprintf(stderr, "Call frame traceback EIPs:\n 0x%08lx\n", npx.eip) ;
exit(1) ;
}
void sub1(void)
{
double x, y ;
x = 10. ;
y = 0. ;
x = x/y ;
}
#ifdef __cplusplus
typedef void (*fptr)(int);
#else
typedef void (*fptr)();
#endif
int main(int argc, char **argv)
{
double x, y ;
/* cast Catcher to appropriate type */
signal(SIGFPE, (fptr)ErrorCatcher);
x = 10. ;
y = 0. ;
printf("Hello, world\n") ;
fflush(stdout) ;
sub1() ;
printf("%lf\n", x) ;
}
- Raw text -