Glibc 在assert.h
中使用 GCC 的noreturn
属性:
extern void __assert_fail (...)
... __attribute__ ((__noreturn__));
这会导致 GCC 在进入调试器之前优化掉所有局部变量和指针this
。优化甚至发生在-Og
级别,并且在-O0
级别上,省略了许多其他有用的优化,以至于测试变得非常缓慢。
理想情况下,我只想从那里删除__noreturn__
属性。我不在乎我的assert()
是否工作得更快一点,我想看看它在哪里以及为什么触发。
是否有 GCC 命令行标志或任何其他机制可用于禁用__noreturn__
优化,而无需禁用其他优化?
可运行的示例代码:
#include <cassert>
int test(int x)
{
assert(x != 1);
return x + 10;
}
int main(int argc, char *argv[])
{
return test(argc);
}
此示例在没有参数的情况下运行时断言。当使用 GCC 7.4 和g++ -Og -g -ggdb -otest test.cc
编译并在 gdb 中运行时,您可以看到回溯是无用的:
#4 0x0000555555554676 in test (x=<optimized out>) at test.cc:4
#5 0x000055555555467f in main (argc=<optimized out>, argv=<optimized out>) at test.cc:9
Jarod42 关于用自定义宏覆盖assert
的评论给出了一个想法:
g++ -D__noreturn__= ...usual options follow...
这只需将属性定义更改为空括号即可。 它并不漂亮,但至少可以工作。
如果有一个关于在 noreturn 调用之前丢弃局部变量或类似的东西的特定优化标志,那就太好了,但我找不到一个。所以这是我迄今为止最好的。