从网上总结了gprof使用的注意事项,说不定以后会用到:
一,gprof只能查看用户函数信息。如果想查看库函数的信息,需要在编译是再加入"-lc_p"编译参数代替"-lc"编译参数,这样程序会链接libc_p.a库,如果系统没有libc_p.a库,需要自己编译这个库。
二,gprof不能产生gmom.out文件的原因:gprof只能在程序正常结束退出之后才能生成程序测评报告,原因是gprof通过在atexit()里注册了一个函数来产生结果信息,任何非正常退出都不会执行atexit()的动作,所以不会产生gmon.out文件。所以,以下情况可能不会有gmon.out文件产生:
1,程序不是从main return或exit()退出,则可能不生成gmon.out。
2,程序如果崩溃,可能不生成gmon.out。
3,测试发现在虚拟机上运行,可能不生成gmon.out。
4,程序忽略SIGPROF信号!一定不能捕获、忽略SIGPROF信号。man手册对SIGPROF的解释是:profiling timer expired. 如果忽略这个信号,gprof的输出则是:Each sample counts as 0.01 seconds. no time accumulated.
5,如果程序运行时间非常短,则gprof可能无效。因为受到启动、初始化、退出等函数运行时间的影响。如果你的程序是一个不会退出的服务程序,那就只有修改代码来达到目的。如果不想改变程序的运行方式,可以添加一个信号处理函数解决问题(这样对代码修改最少),例如:
static void sighandler( int sig_no )
{
exit(0);
}
signal( SIGUSR1, sighandler );
这样当使用kill -USR1 pid 后,程序退出,生成gmon.out文件。
三,多线程使用:
gprof无法分析多线程程序。缘故是gprof使用ITIMER_PROF定时器, 当超时时由内核向应用程序发送信号。但多线程程序只有主线程接收ITIMER_PROF。 这里有一个简单的实现方法: 对pthread_create进行保证,并以动态库的形式在程序运行前加载。
推荐文章:http://blog.****.net/stanjiang2010/article/details/5655143
转自:http://blog.****.net/ym012/article/details/7094700
crazyhacking的代码如下,
#include<signal.h>
#include<iostream>
using namespace std;
static void sighandler(int sig_no);
int main(){
cout<<"begin"<<endl;
signal(SIGUSR1,sighandler);
for(;;){
cout<<"sleep 2"<<endl;
sleep(2);
}
return 1;
}
static void sighandler(int sig_no){
if(sig_no==SIGUSR1)
cout<<"received singal:"<<sig_no<<" ,exit "<<endl;
}
使用如下 : kill -USR1 70924
使用gmoun.out 使用 gprof –b
./hello gmont.out >report 时,查看 Call graph下边的
查看占比 例如, 21.1 0.01 0.12 16255 bfd::migration::jsontomap 占比21%