From owner-freebsd-hackers Wed May 8 19:53:43 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id TAA00569 for hackers-outgoing; Wed, 8 May 1996 19:53:43 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id TAA00535 for ; Wed, 8 May 1996 19:53:21 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id MAA03905; Thu, 9 May 1996 12:47:19 +1000 Date: Thu, 9 May 1996 12:47:19 +1000 From: Bruce Evans Message-Id: <199605090247.MAA03905@godzilla.zeta.org.au> To: alk@Think.COM, hackers@freebsd.org Subject: Re: SIGFPE Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >Does anyone have an example of code which handles SIGFPEs? >I do not understand how to discriminate causes and rectify >problems in a handler, and there does not appear to be any >code in the os which does this, to serve as an example. It's not supported. The best method of handling a SIGFPE is: sig_atomic_t saw_sigfpe; jmp_buf sigfpe_jb; void sigfpe_handler(int s) { saw_sigfpe = 1; longjmp(sigfpe_jb, 1); } Use of floating point in a signal handler (not just the SIGFPE handler) gives undefined behaviour (in FreeBSD-current it trashes the FPU state and may cause a SIGFPE). Something like the following might work in FreeBSD-current. Signal handlers see the process' FPU state directly, so it is easy to change it directly if you know what to change. static struct save87 fpu_state; void sigfpe_handler(int s, int code, struct sigcontext *scp) { switch (code) { case FPE_INTDIV_TRAP: ... break; ... other integer traps ... case 0: /* XXX code for all h/w FP traps. Emulators may be different. */ asm("fnsave _fpu_state"); /* XXX */ fpu_state.sv_ex_sw = ptrace_or_something_to_read_saved_exception_status_from_user_area(); code = decode(fpu_state.sv_ex_sw); ... adjust fpu_state ... asm("frstor _fpu_state"); /* XXX */ break; } Bruce