NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/43655: integer division by zero delivers SIGFPE with wrong siginfo code



>Number:         43655
>Category:       kern
>Synopsis:       integer division by zero delivers SIGFPE with wrong siginfo 
>code on i386
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 22 22:10:01 +0000 2010
>Originator:     Taylor R Campbell <campbell+netbsd%mumble.net@localhost>
>Release:        NetBSD 5.1_RC2
>Organization:
>Environment:
System: NetBSD ... 5.1_RC2 NetBSD 5.1_RC2 (RIAGATE) #0: Mon Jun 21 22:23:02 UTC 
2010 root@.../obj/sys/arch/i386/compile/RIAGATE i386
Architecture: i386
Machine: i386
>Description:

        When the processor traps integer division by zero, NetBSD
        delivers SIGFPE with a siginfo code of FPE_FLTDIV, whereas the
        siginfo code should be FPE_INTDIV.

>How-To-Repeat:

        If the following source code is stored in lose.c, I observe

                % make lose
                cc -O2   -o lose lose.c
                % ./lose 0
                3

        The number 3 is the value of FPE_FLTDIV, as defined in
        <sys/siginfo.h>.  The output should be 1, FPE_INTDIV.  By
        contrast, the same program under Linux, for example, gives 1
        (which is the value of FPE_INTDIV on Linux too).

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

static void
handler (int signal_number, siginfo_t *info, void *context)
{
  int code = (info -> si_code);
  char buffer [1024];
  (void) write (1, buffer, (snprintf (buffer, (sizeof buffer), "%d\n", code)));
  _exit (1);
}

int
main (int argc, char *argv [])
{
  int d = 0;
  static const struct sigaction zero_sa;
  struct sigaction sa_storage = zero_sa, *sa = (&sa_storage);
  (sa -> sa_sigaction) = (&handler);
  (sa -> sa_flags) = SA_SIGINFO;
  (void) sigaction (SIGFPE, sa, 0);
  if (argc < 2) return (1);
  (void) sscanf ((argv [1]), "%d", (&d));
  (void) printf (";%d\n", (1 / d));
  return 0;
}


>Fix:

        Yes, please!



Home | Main Index | Thread Index | Old Index