4

I am debugging a production code written in C and its simplest form can be shown as -

void
test_fun(int sr)
{   
    int hr = 0;
    #define ME 65535
    #define SE 256

    sr = sr/SE;             <--  This should yield 0
    if(sr == 1)
        hr = ME;
    else
        hr = (ME+1)/sr;     <-- We should crash here.
}

We are passing sr as 128, which ideally should yield in divide by zero error in processor. I see that this division happens successfully with quotient as 0x7ffffffff (hr is this value). This does not happens (it crashes when attempts the division by zero) when I compile and run the same on Intel platform with gcc.

Want to to know principle behind this big quotient. Not sure if it is just some other bug I still need to uncover. Can someone help me with another program that does the same?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
ultimate cause
  • 2,264
  • 4
  • 27
  • 44
  • 3
    Integer division-by-zero yields *undefined behaviour*. You should perform an explicit check for `sr == 0`. – Oliver Charlesworth Jun 07 '15 at 16:24
  • I believe, on PowerPC it would yield some kind of exception. Is it running on some OS or bare-metal? – Eugene Sh. Jun 07 '15 at 16:26
  • @Eugene : It has NetBSD 5.1 as Operating System – ultimate cause Jun 07 '15 at 16:27
  • @EugeneSh. according to [this](http://pds.twi.tudelft.nl/vakken/in101/labcourse/instruction-set/divw.html) it just sets a bunch of flags (which the compiler may ignore) – harold Jun 07 '15 at 16:27
  • @harold It is a run-time error, so compiler is out of the loop. I believe on *nix-like systems the SIGFPE should be signalled. – Eugene Sh. Jun 07 '15 at 16:29
  • @Everyone Above : This did not signal SIGFPE either. And I agree that we should perform validation on divisor. Due to a bug in code this bad value was passed here. – ultimate cause Jun 07 '15 at 16:32
  • @EugeneSh.: But the compiler is allowed to generate a signal handler... – Oliver Charlesworth Jun 07 '15 at 16:33
  • what compiler in which precise version are you using? – deets Jun 07 '15 at 16:35
  • @OliverCharlesworth But why would compiler do this? The operands are not constant, how would it know that there is division by zero? Update, oh, I see, you are talking of the handler, sorry. – Eugene Sh. Jun 07 '15 at 16:36
  • @EugeneSh.: It is not guaranteed that SIGFPE is generated. – Dietrich Epp Jun 07 '15 at 16:48
  • @EugeneSh. the point I was trying to make is that it doesn't make a signal. So if there is a signal, it would be because the compiler generated code that tested the overflow flag and then raised the signal. Apparently such code was not generated. This is not a case where the compiler is out of the loop, there is no loop to be out of. – harold Jun 07 '15 at 17:25

2 Answers2

3

Division by zero is undefined behaviour, see C11 standard 6.5.5#5 (final draft).

Getting a trap or SIGFPE is just a courtesy of the CPU/OS. PowerPC as typical RISC CPU does not catch it, as it can safely be detected by a simple check of the divisor right before doing the actual division. x86 OTOH does catch this - typical CISC behaviour.

If required by a higher layer standard, you probably have missed a compiler option which emits this check automatically. POSIX for instance does not enforce SIGFPE, this is optional.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • Thanks. However I think that this big value as quotient is result of some digital algorithm. Want some pointers on that as well. – ultimate cause Jun 07 '15 at 17:15
  • 1
    @RIPUNJAYTRIPATHI: Long division. – Oliver Charlesworth Jun 07 '15 at 17:17
  • @Oliver Charlesworth : I am still searching for this long division algorithm. From your instinct is it that algorithm generates that kind of quotient or does it just puts a distinct/unique value a result of validation of divisor at processor level to denote the error. In other words, Is it possible for a different numerator with divisor 0, to generate a different value of quotient? – ultimate cause Jun 07 '15 at 18:35
  • @RIPUNJAYTRIPATHI: YOu have to ask IBM for that about how they actually implemented the division in their chip. No one except the chip designers can help you with that. Please read about the definition on **undefined behaviour**. That means actually: **anything** can happen. You PC might grow feet and run away. – too honest for this site Jun 07 '15 at 20:10
  • You PC might grow feet and run away. :-) – ultimate cause Jun 07 '15 at 20:12
  • That was just to make clear: there is no use in further going into that direction, as you cannot expect anything predictable to happen. For instance, on ARM (at least Cortex-M3/4) you can enable exceptions for divide-by-0, but that is still not guaranteed. The result you currently get might be just because of temperature variation even. – too honest for this site Jun 07 '15 at 20:16
  • @Olaf - I completely agree the undefined behaviour clause and I also agree with your point w.r.t code fixing. Since the quotient was bad, I understood that, standard way of checking the divisor was the ideal way. However, it seemed interesting to me to know such algorithms. That was absolutely, out of my own interest. Thank you for your answer and help. – ultimate cause Jun 07 '15 at 20:23
  • this matches behaviour I've observed today: I am running same bit of code which does an integer divide-by-zero. On x86 I faitfully get SIGFPE (which I catch with `signal()` on ppc the same bit of code keeps happily executing. – Adam.at.Epsilon Apr 27 '17 at 18:09
  • 1
    @Adam.at.Epsilon: Actually, on x86 there is no guarantee to get SIGFPE either. Taht depends on the OS, etc. If you run the code bare-metal on x86 you need to setup an interrupt handler for the divide-by-zero exception. What that does is completely at your discretion. – too honest for this site Apr 27 '17 at 20:55
  • @Olaf I run the code in Linux, as it happens. We set the flags `-D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=500` for gcc when the app is compiled, was just about to dive into the POSIX spec to find out SIGFPE behaviour. – Adam.at.Epsilon Apr 28 '17 at 08:25
3

Per the PPC architecture manual (which you can get from IBM), divide by 0 on a PPC does not result in any kind of signal or trap; instead, you just get some undefined value that varies from processor to processor. In your case, it looks the particular PPC variant you have generates MAXINT (largest positive integer) when dividing a positive number by 0.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226