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
Accessing Protected Members of Superclass in C++ with Templates
What Destructors Are Run When the Constructor Throws an Exception
Segmentation Fault at Glgenvertexarrays( 1, &Vao );
How to Convert Unsigned Char* to Std::String in C++
Casting via Void* Instead of Using Reinterpret_Cast
C++ Socket Server - Unable to Saturate Cpu
Compiling External C++ Library for Use with iOS Project
How Does Openmp Handle Nested Loops
How to Generate Thread-Safe Uniform Random Numbers
What Is Return Type of Assignment Operator
How to Make an Array with a Dynamic Size? General Usage of Dynamic Arrays (Maybe Pointers Too)
Why Can't Templates Be Within Extern "C" Blocks
Self-Initialization of a Static Constexpr Variable, Is It Well-Formed
Explanation of Function Pointers