Glibc uses GCC's noreturn
attribute in assert.h
:
extern void __assert_fail (...)
... __attribute__ ((__noreturn__));
This causes GCC to optimize away all local variables and this
pointer before breaking into debugger. The optimization happens even at -Og
level, and at -O0
level so many other useful optimizations are omitted that testing becomes painfully slow.
Ideally I would like to just remove the __noreturn__
attribute from there. I don't care if my assert()
works a tiny bit faster, I want to see where and why it fired.
Is there a GCC command line flag or any other mechanism that I can use to disable the __noreturn__
optimization, without disabling other optimizations?
Runnable example code:
#include <cassert>
int test(int x)
{
assert(x != 1);
return x + 10;
}
int main(int argc, char *argv[])
{
return test(argc);
}
This example asserts when it is run without arguments. When compiled with GCC 7.4 with g++ -Og -g -ggdb -otest test.cc
, and running inside gdb, you can see the backtrace is useless:
#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's comment about overwriting
assert
with custom macro gave an idea:This works by just changing the attribute definition into empty brackets. It is not pretty, but it at least works.
It would be nice if there was a somewhat specific optimization flag about discarding local variables before noreturn call, or something similar, but I haven't been able to find one. So this is best I have so far.