我想使用 gcc 选项 -finstrument-functions 获取程序的函数调用堆栈。
典型代码
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
int depth = -1;
void __cyg_profile_func_enter (void *func, void *caller)
{ }
void __cyg_profile_func_exit (void *func, void *caller)
{ }
int main()
{
printf("Hello world");
return 0
}
用 gcc -finstrument-functions test.c 编译
运行./a.out,一切正常。
但是当我使用 g++ 执行此操作时,我得到了对 __cyg_profile_func_enter 函数的 undefined reference 。我读到它发生是因为 _cyg 函数是 C 代码的一部分,如果我想在 C++ 中使用它们,我应该使用 extern "C",所以有最终代码。
extern "C"{
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
int depth = -1;
void __cyg_profile_func_enter (void *func, void *caller)
{ }
void __cyg_profile_func_exit (void *func, void *caller)
{ }
}
int main()
{
printf("Hello world");
return 0
}
它使用 g++ -finstrument-functions test.c 编译,然后尝试执行它但得到了 Core dumped 错误消息。我使用 gdb 跟踪转储,发现 __cyg_profile_func_enter() 中存在段错误。
GCC 版本为 2.95.4。我还在 4.4.3 上测试过,一切正常。那么有没有可能使用 2.95.4 gcc 解决这个问题?
最佳答案
gcc 2.95.4 已经十多年了。我已经设法挖出一个......并编译你的东西。它显然不能识别 __attribute__((no_instrument_function))
因为生成的汇编代码有:
__cyg_profile_func_enter:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp,%ebp
.LCFI1:
subl $8,%esp
.LCFI2:
movl 4(%ebp),%eax
addl $-8,%esp
pushl %eax
pushl $__cyg_profile_func_enter
.LCFI3:
call __cyg_profile_func_enter
movl 4(%ebp),%eax
addl $16,%esp
addl $-8,%esp
pushl %eax
pushl $__cyg_profile_func_enter
call __cyg_profile_func_exit
movl %ebp,%esp
popl %ebp
ret
所以它递归地调用自己,当然以堆栈溢出结束。
如果您真的需要 gcc 2.95.x(面向天堂,翻白眼,脸上畏缩的表情,“为什么哦为什么???”)和 -finstrument-functions
那么你必须让它们成为“真正的 extern
” - 即把它们放在一个单独的源文件中,你编译时没有选项,然后在稍后链接它。
关于c++ - __cyg_profile_func_enter 和 g++ 2.95.4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12528223/