我需要确定共享对象中的一组例程是否应用了gcc的尾部调用优化。 需要一个C代码,最好使用API代替' nm'或者' objdump'系统命令。
任何有关更多信息的链接都会有所帮助
详细说明: 例如。原始C代码就像
void myFunc1(){
... // Do something
myFunc2();
return;
}
转储函数myFunc1的汇编程序代码:
0x57ad50b0 <+0>: push %ebp
0x57ad50b1 <+1>: mov %esp,%ebp
0x57ad50b3 <+3>: mov 0x8(%ebp),%eax
0x57ad50b6 <+6>: pop %ebp
0x57ad50b7 <+7>: lea 0x8(%eax),%edx
0x57ad50ba <+10>: mov (%eax),%eax
0x57ad50bc <+12>: jmp 0x57ab8010 <myFunc2>
我们可以看到最后一条指令不是&#34;调用myFunc2&#34;但只是&#34; jmp myFunc2&#34;。 由于这个原因,我们无法获得有关&#34; myFunc1&#34;的信息。从堆栈跟踪。 所以我们需要事先确定&#34; myFunc1&#34;可以解决这个问题,以便我们解决它。
答案 0 :(得分:0)
最直接的方法是使用编译器转储
int bar (int x);
int
foo (int x)
{
return bar(x);
}
编译:
gcc -O2 -S tailcall.c -fdump-tree-tailc-lineno-details
在转储文件tailcall.c.137t.tailc中,您将看到:
;; Function foo (foo, funcdef_no=0, decl_uid=1721, cgraph_uid=0)
Found tail call [tailcall.c : 6:3] _4 = bar (x_2(D)); [tail call]
接下来,您可以通过这种方式分析您的所有项目。 GCC将编写所有发现尾调用的地方。
但这种方式依赖于gcc版本。我的输出对gcc 4.8.x有效,但对于其他分支,tailcall树的数量,其名称或转储格式可能不同。
如果尾调用问题,那么只需使用-fno-optimize-sibling-calls选项
gcc -O2 -S tailcall.c -fno-optimize-sibling-calls
将产生没有兄弟呼叫的输出。