Reputation: 13
I'm getting this weird behaviour from an executable compiled with different versions of gcc
, all emit the SIGFPE
signal and the best part is that I have no floating point of any kind in my code; if someone could shed some light on this ... I literally don't know where to start to debug this, it's so weird and this bug is triggered by all the gcc installations that I have from 4.9
to 6.0
.
Here is a snippet that reproduces the problem
// Floating point exception - SIGFPE
#include <stdio.h>
typedef unsigned int T;
int main()
{
#define N 256
for (T i = 0; i < N; ++i)
{
i += (i % i);
printf("%u\t", i);
}
}
// bug uncovered with
// gcc version 4.9.2 (Debian 4.9.2-10)
// gcc version 5.1.0 (GCC)
// gcc version 6.0.0 20150517 (experimental) (GCC)
// using -std=c11 or -std=c99
The purpose of this code is to reproduce the problem, I know that the logic of it doesn't really make too much sense ( the modulo part ) but clang
passes the test, no version of gcc
does the same and I would like to know why if there is a technical explanation for this kind of behaviour .
Upvotes: 1
Views: 1161
Reputation: 12263
Do not complain if demons crawl up your keyboard when using undefined behaviour (UB):
C11 draft, 6.5.5#5: "The result of the / operator ... the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined."
UB can be anything. You should actually be happy to get an exception, whatever it is called (it actually does even show the correct reason) and not just have the program produce wrong results unnoticed (the worst that can actually happen!). For many CPUs, you will not notice anything. Just enable compiler warnings; that might help detect such cases (yet not guranteed).
Upvotes: 0
Reputation: 34592
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.
Upvotes: 2