Why Does A%B Produce Sigfpe When B Is Zero

Why does a%b produce SIGFPE when b is zero?

The operation triggers SIGFPE:

SIG is a common prefix for signal
names; FPE is an acronym for
floating-point exception. Although
SIGFPE does not necessarily involve
floating-point arithmetic, there is no
way to change its name without
breaking backward compatibility.

GDB is a bit clearer about this and calls it "Arithmetic exception":

(gdb) run
Starting program: /home/emil/float

Program received signal SIGFPE, Arithmetic exception.
0x0804837d in main () at float.c:4
4 int c=a%b;

Floating point exception without division by zero

What should I do to resolve this problem?

The first thing to address this problem would be to have a look at the hints your compiler is able to provide you. That is, enable warnings (-Wall) and debugging symbols (-g):

$ gcc test.c -Wall -g
test.c: In function ‘main’:
test.c:25:11: warning: ‘c’ may be used uninitialized in this function [-Wuninitialized]

There may be something wrong with the variable c in line 25, which is exactly the print statement:

printf("%d",(b%c));

Let's see what happens when we run it:

$ ./a.out
1
2
3
Floating point exception (core dumped)

Ah, well, it fails. But how did it crash? That's a use case for gdb:

$ gdb ./a.out
GNU gdb (GDB) Fedora (7.5.1-37.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/moooeeeep/a.out...done.
(gdb) run
Starting program: /home/moooeeeep/a.out
1
2
3

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400640 in main () at test.c:25
25 printf("%d",(b%c));
Missing separate debuginfos, use: debuginfo-install glibc-2.16-30.fc18.x86_64

Just at line 25. Suspicious. Let's examine the contents of the variables:

(gdb) print b
$1 = 1
(gdb) print c
$2 = 0

That variable c is indeed zero. But why is it causing a floating point exception when there are only integers? (Others have observed this before you.) As you can see in the debugger it's called an arithmetic exception (c.f.):

The SIGFPE signal reports a fatal arithmetic error. Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow.

Let's see what valgrind tells us:

$ valgrind ./a.out
==3113== Memcheck, a memory error detector
==3113== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3113== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3113== Command: ./a.out
==3113==
1
2
3
==3113==
==3113== Process terminating with default action of signal 8 (SIGFPE)
==3113== Integer divide by zero at address 0x403E58A5B
==3113== at 0x400640: main (test.c:25)
==3113==
==3113== HEAP SUMMARY:
==3113== in use at exit: 0 bytes in 0 blocks
==3113== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3113==
==3113== All heap blocks were freed -- no leaks are possible
==3113==
==3113== For counts of detected and suppressed errors, rerun with: -v
==3113== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Floating point exception (core dumped)

valgrind identified an integer division by zero exactly at line 25. You should have an eye on that line (and the variables involved)!


Note that most IDEs (e.g., Eclipse) have (some of) these tools directly integrated, which makes debugging really a charm.

Why do I get a floating-point exception on modulo operation after a call to realloc()?

I thought the first if statement would catch that issue, because
printf("%f", primes[tested]) prints 0. However, it doesn't and the
"break" is not executed.

You test whether primes[tested] == 0, but your code is only valid if ((int)primes[tested]) == 0. These are not at all the same thing. Moreover, printing the value of primes[tested] with format %f does not reliably tell you differently, because it gives you only 6 digits after the decimal point. Try a "%e" format instead, and test the condition you actually require, not a related, weaker one.

But even better, don't use a floating-point type here. FP has no business being used in a discrete math problem, such as you appear to be trying to solve. If primes[tested] in fact holds prime or possibly-prime numbers then unsigned long long int likely has the same size as double, and almost surely can exactly represent a wider range of primes. Or if it just contains flags, such as in a prime number sieve, then anything wider than char is wasteful.

Floating point exception without division by zero

What should I do to resolve this problem?

The first thing to address this problem would be to have a look at the hints your compiler is able to provide you. That is, enable warnings (-Wall) and debugging symbols (-g):

$ gcc test.c -Wall -g
test.c: In function ‘main’:
test.c:25:11: warning: ‘c’ may be used uninitialized in this function [-Wuninitialized]

There may be something wrong with the variable c in line 25, which is exactly the print statement:

printf("%d",(b%c));

Let's see what happens when we run it:

$ ./a.out
1
2
3
Floating point exception (core dumped)

Ah, well, it fails. But how did it crash? That's a use case for gdb:

$ gdb ./a.out
GNU gdb (GDB) Fedora (7.5.1-37.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/moooeeeep/a.out...done.
(gdb) run
Starting program: /home/moooeeeep/a.out
1
2
3

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400640 in main () at test.c:25
25 printf("%d",(b%c));
Missing separate debuginfos, use: debuginfo-install glibc-2.16-30.fc18.x86_64

Just at line 25. Suspicious. Let's examine the contents of the variables:

(gdb) print b
$1 = 1
(gdb) print c
$2 = 0

That variable c is indeed zero. But why is it causing a floating point exception when there are only integers? (Others have observed this before you.) As you can see in the debugger it's called an arithmetic exception (c.f.):

The SIGFPE signal reports a fatal arithmetic error. Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow.

Let's see what valgrind tells us:

$ valgrind ./a.out
==3113== Memcheck, a memory error detector
==3113== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3113== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3113== Command: ./a.out
==3113==
1
2
3
==3113==
==3113== Process terminating with default action of signal 8 (SIGFPE)
==3113== Integer divide by zero at address 0x403E58A5B
==3113== at 0x400640: main (test.c:25)
==3113==
==3113== HEAP SUMMARY:
==3113== in use at exit: 0 bytes in 0 blocks
==3113== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3113==
==3113== All heap blocks were freed -- no leaks are possible
==3113==
==3113== For counts of detected and suppressed errors, rerun with: -v
==3113== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Floating point exception (core dumped)

valgrind identified an integer division by zero exactly at line 25. You should have an eye on that line (and the variables involved)!


Note that most IDEs (e.g., Eclipse) have (some of) these tools directly integrated, which makes debugging really a charm.

How to produce codes that always trigger signal SIGFPE(div by zero)?

I think that ChrisDodd's answer is the most precise one.
I.e. the return value of do_div_by_0 is ignored, so that the compiler optimizes out the division operation.

We need to use the return value when we call do_div_by_0, like follows:

TEST_F( SignalsHandling_F, divByZeroDying ) {
ASSERT_EXIT( {
std::cerr << do_div_by_0();

// never should go here!
exit( EXIT_SUCCESS );

}, KilledBySignal( SIGFPE ), "" );
};

It works!

Thanks everybody!!!

Division by zero does not throw SIGFPE

For floating point numbers you can change this behavior by setting up FPU control word. Take a look here

SIGFPE with gcc and unsigned integers

After running the code, this was under cygwin, gdb dumped the trace.

$ cat sigfpe.exe.stackdump
Exception: STATUS_INTEGER_DIVIDE_BY_ZERO at rip=00100401115
rax=0000000000000000 rbx=000000000022CB20 rcx=0000000000000001
rdx=0000000000000000 rsi=000000060003A2F0 rdi=0000000000000000
r8 =0000000000000000 r9 =0000000000000000 r10=0000000000230000
r11=0000000000000002 r12=0000000000000000 r13=0000000000000001
r14=000000000022CB63 r15=000000000022CB64
rbp=000000000022CAD0 rsp=000000000022CAA0
program=C:\cygwin64\home\luser\sigfpe.exe, pid 6808, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0000022CAD0 00100401115 (00000000020, 30001000000FF00, 0018004830F, 0000022D680 )
0000022CBC0 00180048380 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 0018004607C (00000000000, 0003E704021, 00000000000, 0000000002D)
00000000000 00180046114 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00100401191 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00100401010 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 000772E59CD (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 0007741B981 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

The clue is in the operation i += (i % i)

when the loop is initial value of 0, of course, divide by zero error.

Have you tried to catch the signal?

Look at the C11 standard on Page 265, SIGFPE - an erroneous arithmetic operation, such as zero divide or an operation resulting in overflow

It is not a compiler bug, that is implementation defined.



Related Topics



Leave a reply



Submit