服务器性能分析工具gprof的使用及没有生成gmon.out文件的原因

本文介绍了gprof性能分析工具的使用方法及注意事项,包括如何获取更全面的调用时间数据、解决gmom.out文件生成问题、多线程环境下的使用限制及应对策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


        早上从网上查看资料时无意中看到了gprof这个工具,随便把他用在项目里试了一下。结果发现调用次数的数据比较全,但调用时间基本上都是0。网上查了一下发现gprof只记录执行时间超过0.01秒即10毫秒的函数调用时间:*(,我测的是服务器程序,这个时间也太长了吧!!!!
        从网上总结了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.youkuaiyun.com/stanjiang2010/article/details/5655143


转自:http://blog.youkuaiyun.com/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%

### 解决方案 `gprof` 是 GNU 提供的一个性能分析工具,它通过生成 `gmon.out` 文件来记录程序运行时的性能数据。当执行 `gprof` 命令时报错提示 `gmon.out` 文件不存在时,通常意味着该文件未被成功创建或丢失。 以下是可能导致此问题的原因及其对应的解决方案: #### 1. **忘记编译时启用 `-pg` 参数** 为了使 `gprof` 能够正常工作,在编译源代码时需要加上 `-pg` 参数以便链接必要的库并插入性能监控代码[^1]。 ```bash gcc -o my_program my_program.c -pg ``` 如果没有加这个参数,则即使运行了可执行文件也不会生成 `gmon.out` 文件。 --- #### 2. **未实际运行目标程序** 仅仅编译带有 `-pg` 的程序并不足以生成 `gmon.out` 文件;还需要真正运行生成的目标二进制文件才能触发其内部机制去收集统计数据[^4]。 ```bash ./my_program ``` 只有这样才会在当前目录下留下名为 `gmon.out` 的输出文档作为后续处理依据。 --- #### 3. **权限不足或者路径设置不当** 有时尽管完成了上述操作但仍找不到预期中的 `gmon.out` ,这可能是由于操作系统层面的因素造成的干扰——比如写入权限受限或者是默认保存位置发生了改变等原因所致。可以通过下面方法确认具体情况: - 检查是否有足够的磁盘空间可用; - 使用绝对路径指定临时存储区域给环境变量 `$GMON_OUT_PREFIX` 来强制更改输出地点: ```bash export GMON_OUT_PREFIX=/desired/path/gmon.out ``` 之后再次尝试启动应用程序看看能否按新设定产出相应结果。 --- #### 4. **多线程或多进程场景下的特殊行为** 对于某些复杂的并发结构(如涉及子进程 fork 或者多个独立线程),单一全局性的 `gmon.out` 可能不足以全面反映整个系统的状况。此时每个单独实例可能会各自生产属于自己的采样资料集,并分别命名为类似于 `gmon.pid.out` 这样的形式[^2] 。因此建议仔细查找是否存在类似的变体命名模式的数据单元存在于作业所在的根目录之中。 --- #### 工具链补充说明 除了基础版 `gprof`, 开发人员还可以考虑采用更先进的替代品来进行深入剖析, 如提到过的 Callgrind/Valgrind 组合以及 Linux 自带 Perf Tools 等高级选项, 它们能够提供更为详尽且直观的表现指标解读视角. 最后附上一段简单的脚本示范如何利用 gprof2dot 结合 graphviz 自动生成可视化的调用关系图表: ```python import os os.system('gprof ./my_program | gprof2dot > profile.dot') os.system('dot -Tpng profile.dot -o profile.png && eog profile.png &') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值