由于这个问题在搜索结果中非常突出,我将添加另一种方法,比其他列出的方法更简便的方法:uftrace。
它需要使用-pg -g(或者如果您只对函数名称感兴趣而不关心参数和返回值,则使用-finstrument-functions)编译相应的应用程序。
然后,您可以交互式地运行该命令:
uftrace -a --no-libcall -f none <cmd>
或者,也可以先记录追踪数据,然后单独输出。
uftrace record -a --no-libcall -f none <cmd>
uftrace replay
后者也可以跨平台工作,例如,您可以在A系统上运行记录阶段,将跟踪数据(目录
uftrace.data
)传输到B系统,然后在B机器上进行回放。
使用的选项:
-a
启用所有参数和返回值的输出
--no-libcall
隐藏所有标准libc函数
-f none
隐藏通常在前面打印的持续时间和线程ID列
另一个有用的选项是
-N
,例如,
-N log_*
过滤掉所有以
log_
开头的函数调用。更多信息请参阅
uftrace-replay
的man页。
如果输出缺少返回值,请在禁用链接时优化后重试。由于某种原因,这在我的测试中使它们隐藏起来。
使用原始选项交互式运行OP的示例(注意:30是程序输出到stdout的结果):
# uftrace a.out
30
# DURATION TID FUNCTION
0.671 us [802533] | __monstartup();
0.421 us [802533] | __cxa_atexit();
[802533] | main() {
0.060 us [802533] | triple();
11.882 us [802533] | printf();
12.263 us [802533] | }
C++ fac示例只是展示了要点:
# uftrace --no-libcall -a a.out
1
1
2
6
# DURATION TID FUNCTION
[803250] | _GLOBAL__sub_I_fac() {
107.551 us [803250] | __static_initialization_and_destruction_0(1, 65535);
108.473 us [803250] | }
[803250] | main() {
0.211 us [803250] | fac(0) = 1;
[803250] | fac(1) {
0.080 us [803250] | fac(0) = 1;
0.491 us [803250] | } = 1;
[803250] | fac(2) {
[803250] | fac(1) {
0.070 us [803250] | fac(0) = 1;
0.340 us [803250] | } = 1;
0.541 us [803250] | } = 2;
[803250] | fac(3) {
[803250] | fac(2) {
[803250] | fac(1) {
2.464 us [803250] | fac(0) = 1;
2.725 us [803250] | } = 1;
2.916 us [803250] | } = 2;
3.086 us [803250] | } = 6;
33.463 us [803250] | } = 0;