Glibc在noreturn
中使用GCC的assert.h
属性:
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);
}
此示例在不带参数的情况下运行时断言。当使用带有g++ -Og -g -ggdb -otest test.cc
的GCC 7.4进行编译并在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
答案 0 :(得分:0)
Jarod42关于使用自定义宏覆盖assert
的评论给出了一个主意:
g++ -D__noreturn__= ...usual options follow...
这仅通过将属性定义更改为空括号而起作用。 它不漂亮,但至少可以正常工作。
如果有一个关于在noreturn调用之前或类似的操作之前丢弃局部变量的特定优化标记,那会很好,但是我一直找不到。所以到目前为止,这是我最好的。