假设我有来自许多不同地方的称为LOT的功能。所以我想找出谁最能称这个功能。例如,前5个呼叫者或曾经调用此功能超过N次。
我使用的是AS3 Linux,gcc 3.4。
现在我只是设置一个断点,然后每隔300次就停在那里,这样就可以强制它......
有谁知道可以帮助我的工具?
由于
答案 0 :(得分:18)
使用-pg选项编译,运行程序一段时间,然后使用gprof。运行使用-pg选项编译的程序将生成带有执行配置文件的gmon.out文件。 gprof可以读取此文件并以可读的形式呈现。
答案 1 :(得分:2)
分析有帮助。
答案 2 :(得分:2)
我写了一个呼叫记录示例只是为了好玩。宏用函数调用函数调用函数调用。
include <stdio.h>.
int funcA( int a, int b ){ return a+b; }
// instrumentation
void call_log(const char*file,const char*function,const int line,const char*args){
printf("file:%s line: %i function: %s args: %s\n",file,line,function,args);
}
#define funcA(...) \
(call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), funcA(__VA_ARGS__)).
// testing
void funcB(void){
funcA(7,8);
}
int main(void){
int x = funcA(1,2)+
funcA(3,4);
printf( "x: %i (==10)\n", x );
funcA(5,6);
funcB();
}
输出:
file:main.c line: 22 function: main args: 1,2
file:main.c line: 24 function: main args: 3,4
x: 10 (==10)
file:main.c line: 28 function: main args: 5,6
file:main.c line: 17 function: funcB args: 7,8
答案 3 :(得分:1)
由于你在另一条评论中提到了oprofile,我会说oprofile支持在配置文件程序中生成调用图。
有关详细信息,请参阅http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph。
值得注意的是,这肯定不如您从gprof或其他探查器获得的调用者配置文件那样清晰,因为它报告的数字是oprofile收集样本的次数,其中X是给定函数的调用者,不是X称为给定函数的次数。但这应该足以找出给定函数的顶级调用者。
答案 4 :(得分:1)
一种有点麻烦的方法,但不需要额外的工具:
#define COUNTED_CALL( fn, ...) do{ \
fprintf( call_log_fp, "%s->%s\n", __FUNCTION__, #fn ) ; \
(fn)(__VA_ARGS__) ; \
}while(0) ;
然后所有的电话都写成:
int input_available = COUNTED_CALL( scanf, "%s", &instring ) ;
将被记录到与call_log_fp相关联的文件中(您必须初始化的全局FILE *)。上面的日志如下所示:
main->scanf
然后,您可以处理该日志文件以提取所需的数据。您甚至可以编写自己的代码来执行可能不那么麻烦的检测。
虽然可能对C ++类成员函数有点模棱两可。我不确定是否有__CLASS__宏。
答案 5 :(得分:0)
除了前面提到的gprof profiler之外,您还可以尝试使用gcov代码覆盖率工具。有关编译和使用两者的信息应包含在gcc手册中。
答案 6 :(得分:0)
再次stack sampling to the rescue!只需要一堆“stackshots”,尽可能多。丢弃任何样本,其中您的函数(称为F)不在堆栈的某个位置。 (如果丢弃大部分内容,那么F不是性能问题。)
在每个剩余的样本上,找到对F的调用,并查看该调用所在的函数(称之为G)。如果F是递归的(它在样本上出现多次),则只使用最顶层的调用。
根据每个人出现的筹码数量对你的Gs进行排名。
如果您不想手动执行此操作,则可以创建一个简单的工具或脚本。您不需要多个样本。 20左右会给你相当不错的信息。
顺便说一句,如果您真正想要做的是发现性能问题,那么您实际上并不需要做所有丢弃和排名。实际上 - 不要丢弃每个G内部的调用指令的确切位置。这些实际上可以告诉你的不仅仅是它们位于G内部的事实。
P.S。这完全基于这样的假设:当你说“最多叫它”时你的意思是“花费最多的挂钟时间来调用它”,而不是“把它称为最多次”。如果您对性能感兴趣,挂钟时间的一小部分比调用计数更有用。