c++unit-testingoptimizationdivide-by-zerosigfpe

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


I need to code a unit-test that should always trigger a divided by zero signal (SIGFPE), so I can test and compare what would happen with/without my signal catching module.

My Linux signal catching/resuming module has been developed, and worked as expecting. When I'm coding the unit-test for the module, I encounter a small trouble.

These are the UT codes (by means of GTest):

int do_div_by_0() {
    int j = 0;
    return 123 / j; /* During release-building, this div-op would be optimized out,
                       although it would be not when debug-building! */
};

TEST_F( SignalsHandling_F, divByZeroDying ) {
   ASSERT_EXIT( {
      do_div_by_0();
      
      // never should go here!
      exit( EXIT_SUCCESS );

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

If all codes are built in Debug mode, there's no problem. But the division operation would be optimized out in Release mode, as a result the SIGFPE signal would Never be triggered!

To keep the consistency between product codes and testing codes, I must build them all in release mode when I release my product.

How to compose a piece of code that always trigger the signal SIGFPE?

I don't want to use raise() function if a more "actual" method exists, because I want to actually trigger out SIGFPE signal.


Solution

  • 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!