Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 May 1996 12:47:19 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        alk@Think.COM, hackers@freebsd.org
Subject:   Re: SIGFPE
Message-ID:  <199605090247.MAA03905@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605090247.MAA03905>