From owner-freebsd-hackers Sat Sep 21 06:29:13 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id GAA29105 for hackers-outgoing; Sat, 21 Sep 1996 06:29:13 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id GAA29038 for ; Sat, 21 Sep 1996 06:29:07 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.7.6/8.6.9) id XAA18730; Sat, 21 Sep 1996 23:23:30 +1000 Date: Sat, 21 Sep 1996 23:23:30 +1000 From: Bruce Evans Message-Id: <199609211323.XAA18730@godzilla.zeta.org.au> To: candy@fct.kgc.co.jp, hackers@freebsd.org Subject: Re: SIGFPE and signal(3) Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >Hello. Next program never ends. Why? And how can I handle SIGFPE? On the i386, division instructions that trap are restarted if the signal handler just returns (use gdb to see this). longjmp() in the signal handler is the only simple way to escape from the trap. The main code should be something like: if (setjmp(jb)) fix_up_or_give_up(); else code_that_might_trap(); If there is a large amount of code that might trap, then you won't have much idea where the problem occured, so fixing it is impractical, but giving up might be reasonable. Returning from the SIGFPE handler for a floating point trap is also usually wrong, but may sort of work on the i386 because of the different way that the FPU works and more possibilities for kernel trap handling. FPU instructions that trap are also restarted; however, kernels normally clear the FPU exception bits before calling the signal handler, and FPU instructions that cause an exception don't trap until the next FPU instruction after the one that caused the exception. Thus execution normally proceeds beyond the instruction that caused the original trap. The FPU state is undefined after a SIGFPE, unless the SIGFPE handler calls longjmp(), when (in FreeBSD) it the state is restored to almost the one at the time of the corresponding setjmp(). (The state is actually something like: in -current, all registers are empty, which is usually the wrong state for returning from the signal handler with; in my version, the state is the same as when the trap occured except the exception mask is cleared.) Bruce >-------------------- >#include >#include > >void >f(int x) >{ > fprintf(stderr, "x = %d\n", x); >} > >int x = 1, y = 0; > >main() >{ > int z; > signal(SIGFPE, f); > printf("start\n"); > z = x / y; > printf("%d\n", z); >} >-------------------