Currently, I am writing a signal handler for ARM to provide as much debug information as I can. For testing purposes, I cause different calamities. The signal I receive isSIGFPE
, as expected, but the si_code differs from what I expected. I am wondering, why the si_code for integer division with zero is set to SI_TKILL
instead of FPE_INTDIV
or any other SIGFPE
si_code on ARM.
The following function is used to cause the error:
int divide_by_zero()
{
int c = 1;
int b = 0;
return c / b;
}
Is this the default behavior? Are the si_codes on ARM reduced?
I use the arm-linux-gcc compiler for the target which is provided by Buildroot.
According to POSIX, division by zero yields an undefined result, and on some architectures, it will generate a SIGFPE signal.
On the other hand, the Run-time ABI for the ARM Architecture, 4.3.2 Division by zero:
If an integer or long long division helper function is called upon to divide by 0, it should return as quotient the value returned by a call to __aeabi_idiv0 or __aeabi_ldiv0, respectively. A *divmod helper should return as remainder either 0 or the original numerator.
(Aside: Ideally, a *divmod function should return {infinity, 0} or {0, numerator}, where infinity is an approximation. End aside). The *div0 functions:
Return the value passed to them as a parameter.
Or, return a fixed value defined by the execution environment (such as 0).
Or, raise a signal (often SIGFPE) or throw an exception, and do not return.
So implicity, both are indicating that a signal or exception instead of FPE_INTDIV
when an integer zero division is performed is possible and valid.