在gprof输出中查看静态调用

时间:2014-07-07 18:36:36

标签: c gprof

我有一个gprof“flat profile”输出,它列出了我的所有功能,包括静态功能。但是,对于声明为“static”的函数,“calls”,“self ms / call”和“total ms / call”列都是空的。我想看看这些功能的数据;实际上,它们比模块中的公共函数更有趣。例如:

%   cumulative   self              self     total           
time   seconds   seconds    calls  ms/call  ms/call  name    
55.32      3.38     3.38                             Static_Func1
16.61      4.39     1.01                             Static_Func2
12.44      5.16     0.76        2   380.00   380.00  Public_Func1
 9.90      5.76     0.60                             Static_Func3
 2.78      5.93     0.17                             Static_Func4
 0.98      5.99     0.06 12463589     0.00     0.00  main
 0.65      6.03     0.04  1200000     0.00     0.00  Public_Func2
 0.33      6.05     0.02        2    10.00    10.00  Public_Func3
 0.33      6.07     0.02                             Static_Func5
 0.33      6.09     0.02                             free
 0.33      6.11     0.02                             malloc
 0.00      6.11     0.00        1     0.00     0.00  Public_Func4

我发现Why does gprof occasionally not print number of calls for particular functions?解释为什么我没有看到这些函数的输出,但除了去除静态声明之外,还有办法看到它吗?我知道我可以使用-a来禁止打印静态函数,但我想做相反的操作并且看不到它的选项。

当我编辑代码以从上面的配置文件中的静态函数中去掉“static”关键字时,main的“调用”变为空(我期望1,所以这两种方式都是错误的)。更有用的是,不仅填充了字段,而且还列出了由这些静态函数调用的任何函数。我希望能够在没有任何代码更改的情况下做到这一点。

我还发现Is GNU gprof buggy?似乎遇到了同样的问题,但解决方法是编辑代码以强制编译器不要内联某些函数。我不想仅仅为了分析而编辑我的代码,我希望能够看到我现在存在的所有功能。


版本信息,在Windows 7 64位下的MinGW shell中运行:

$ which gprof
/mingw/bin/gprof.exe

$ gprof --version
GNU gprof (GNU Binutils) 2.22
Based on BSD gprof, copyright 1983 Regents of the University of California.
This program is free software.  This program has absolutely no warranty.

1 个答案:

答案 0 :(得分:0)

我不是在这里尝试回答,而是我在cygwinGNU gprof (GNU Binutils) 2.24.51.20140528中遇到的同样问题的进一步延续(我已在Ubuntu上运行此代码(均为32/64)比特)我没有遇到任何问题):

#include<stdio.h>
#include<stdlib.h>

#define N1 100
#define N2 100
#define N3 100
#define N4 100

#define USE_STATIC

#ifdef USE_STATIC
static
#endif
void f5() {
    int i;
    for (i = 0; i < 10; i++) {
    }
}

#ifdef USE_STATIC
static
#endif
void f4()  {
    int i;
    for (i = 0; i < N4; i++) {
        f5();
    }
}

#ifdef USE_STATIC
static
#endif
void f3() {
    int i;
    for (i = 0; i < N3; i++) {
        f4();
    }
}

void f2() {
    int i;
    for (i = 0; i < N2; i++) {
         f3();
    }
}

void f1() {
    int i;
    for (i = 0; i < N1; i++) {
        f2();
    }
}

int main() {
    f1();
    return 0;
}

禁用USE_STATIC宏我得到gprof报告的这个平面数据(这似乎是合理的):

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls   s/call   s/call  name
 85.90      1.98     1.98 100000000     0.00     0.00  f5
  9.98      2.21     0.23                             _mcount_private
  3.47      2.29     0.08  1000000     0.00     0.00  f4
  0.65      2.31     0.01                             _fentry__
  0.00      2.31     0.00    10000     0.00     0.00  f3
  0.00      2.31     0.00      100     0.00     0.02  f2
  0.00      2.31     0.00        1     0.00     2.06  f1

现在,如果我启用它,它就会崩溃:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  Ts/call  Ts/call  name
 79.48      1.82     1.82                             f5
 17.47      2.22     0.40                             _mcount_private
  2.18      2.27     0.05                             f4
  0.44      2.28     0.01                             _fentry__
  0.44      2.29     0.01                             f3
  0.00      2.29     0.00 101010000     0.00     0.00  __gcc_deregister_frame
  0.00      2.29     0.00      100     0.00     0.00  f2
  0.00      2.29     0.00        1     0.00     0.00  f1

至于我能够确定mcount()在每个函数中被正确调用,所以我不知道是什么让gprof混乱,调用数量如此糟糕。毕竟这应该是它能够输出的唯一精确数据。无论如何,时序信息完全不可靠(特别是对于快速完成的程序)。

这里有一个历史的stackoverflow主题,列出了gprof的一些更好的替代方案:http://archive.today/9r927

你可能想看看那里。我知道我会...