微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何产生始终触发信号SIGFPE除以零的代码?

如何解决如何产生始终触发信号SIGFPE除以零的代码?

我需要编写一个单元测试,该单元测试应始终触发零信号除法(SIGFPE),这样我就可以测试和比较使用/不使用信号捕获模块时会发生的情况。

我的Linux信号捕获/恢复模块已开发,并按预期工作。 在为模块的单元测试编写代码时,遇到了一个小麻烦。

这些是UT代码(通过GTest):

int do_div_by_0() {
    int j = 0;
    return 123 / j; /* During release-buidling,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 ),"" );
};

如果所有代码都以调试模式构建,则没有问题。但是除法操作会在“释放”模式下进行优化,结果将永远不会触发SIGFPE信号!

要保持产品代码和测试代码间的一致性,我必须在发布产品时以发布模式构建它们。

如何编写始终触发信号SIGFPE的代码

如果存在更“实际”的方法,我不想使用raise()函数,因为我想实际触发SIGFPE信号。

谢谢!请原谅我的英语不好!

解决方法

int do_div_by_0() {
   int j = 0;
   FILE *f = fopen("/tmp/foobar","r");
   if (f) {
     fscanf(f,"%d",&j);
     fclose(f);
   };
   return 123 / j; /* During release-buidling,this div-op would be optimized out,although it would be not when debug-building! */
};

可能是一个解决方案。当前的GCC编译器(因此2020年9月GCC 10)在运行时(即使使用/tmp/foobar进行了强烈优化)也无法弄清文件gcc -O3 -Wall的内容。 / p>

当然,一个严肃的测试案例将涉及一些填充/tmp/foobar的shell脚本,并使用一些environ(7)变量作为文件名。另请参见mktemp(1),以在测试Shell脚本中使用。

,

我认为ChrisDodd的答案是最精确的答案。 即 do_div_by_0的返回值将被忽略,以便编译器优化除法运算

我们在调用do_div_by_0时需要使用返回值,如下所示:

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

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

有效!

谢谢大家!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。