【发布时间】:2021-01-09 23:31:14
【问题描述】:
我需要编写一个应该始终触发除以零信号 (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 ), "" );
};
如果所有代码都在调试模式下构建,则没有问题。但是除法运算在 Release 模式下会被优化掉,因此 SIGFPE 信号永远不会被触发!
为了保持产品代码和测试代码的一致性,我必须在发布产品时将它们全部构建为发布模式。
如何编写一段总是触发信号SIGFPE的代码?
如果存在更“实际”的方法,我不想使用 raise() 函数,因为我想实际触发 SIGFPE 信号。
谢谢!请原谅我糟糕的英语!
【问题讨论】:
-
您是否尝试在全局范围内简单地声明
j?编译器无法证明j,即使它被初始化为0,也不可能在另一个翻译单元中被修改。 -
或者使用
volatile限定符。 -
通常为了避免此类问题,您需要将一些测试代码放在不同的编译单元中,这样编译器就无法在它们之间进行优化。即使这样,如果启用链接时间优化,您也会遇到问题。
标签: c++ unit-testing optimization divide-by-zero sigfpe