如何解决如何产生始终触发信号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 举报,一经查实,本站将立刻删除。