程序分析是以某种语言书写的程序为对象,对其内部的运作流程进行分析。程序分析的目的主要有三点:一是通过程序内部各个模块之间的调用关系,整体上把握程序的运行流程,从而更好地理解程序,从中汲取有价值的内容。二是以系统优化为目的,通过对程序中关键函数的跟踪或者运行时信息的统计,找到系统性能的瓶颈,从而采取进一步行动对程序进行优化。最后一点,程序分析也有可能用于系统测试和程序调试中。当系统跟踪起来比较复杂,而某个BUG又比较难找时,可以通过一些特殊的数据构造一个测试用例,然后将分析到的函数调用关系和运行时实际的函数调用关系进行对比,从而找出错误代码的位置。

程序分析工具不同于调试器,它只产生程序运行时某些函数的调用次数、执行时间等等宏观信息,而不是每条语句执行时的详细信息。Gprof是Linux下一个强有力的程序分析工具。对于C、Pascal或者Fortran77语言的程序,它能够以“日志”的形式记录程序运行时的统计信息:程序运行中各个函数消耗的时间和函数调用关系,以及每个函数被调用的次数等等。从而可以帮助程序员找出众多函数中耗时最多的函数,也可以帮助程序员分析程序的运行流程。相信这些功能对于分析开源代码的程序员来说,有着相当大的诱惑力。

用gprof分析程序

用gprof对程序进行分析主要分以下三个步骤:

l         用编译器对程序进行编译,加上-pg参数。

l         运行编译后的程序。

l         用gprof命令查看程序的运行时信息。

先以一个简单的例子演示一下吧。随便找一个能够运行的程序的源代码,比如下面的文件test.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void my_print (char *);
static void my_print2 (char *);
main ()
{
char my_string[] = "hello world!";
my_print (my_string);
my_print2 (my_string);
my_print (my_string);
}
void count_sum()
{
int i,sum=0;
for(i=0; i<1000000; i++)
sum += i;
}
void my_print (char *string)
{
count_sum();
printf ("The string is %s ", string);
}
void my_print2 (char *string)
{
char *string2; int size, i,sum =0; count_sum();
size = strlen (string);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size -1 - i] = string[i]; string2[size] =' ';
for(i=0; i<5000000; i++)
sum += i;
printf ("The string printed backward is %s ", string2);
} 

首先,用以下命令进行编译:

[root@localhost]#gcc –o test –pg test.c

然后,运行可执行文件test.

[root@localhost]#./test

运行后,在当前目录下将生成一个文件gmon.out,这就是gprof生成的文件,保存有程序运行期间函数调用等信息。

最后,用gprof命令查看gmon.out保存的信息:

[root@localhost]#gprof test gmon.out –b

这样就有一大堆信息输出到屏幕上,有函数执行单间,函数调用关系图等等,如下:

也可以使用命令$ gprof hello | more

以上介绍了gprof最简单的使用方法,下面针对其使用过程中的三个步骤详细说明。

编译和链接

上面的例子中,程序比较简单,只有一个文件。如果源代码有多个文件,或者代码结构比较复杂,编译过程中先生成若干个目标文件,然后又由链接器将这些目标文件链接到一起,这时该怎么使用gprof呢?

对于由多个源文件组成的程序,编译时需要在生成每个.o文件的时候加上-pg参数,同时在链接的时候也要加上-pg参数。对于链接器不是GCC的情况,如ld,又有特殊的要求。

同时,-pg参数只能记录源代码中各个函数的调用关系,而不能记录库函数的调用情况。要想记录每个库函数的调用情况,链接的时候必须指定库函数的动态(或者静态)链接库libc_p.a,即加上-lc_p,而不是-lc。

还要说明的是,如果有一部分代码在编译时指定了-pg参数,而另一部分代码没有指定,则生成的gmon.out文件中将缺少一部分函数,也没有那些函数的调用关系。但是并不影响gprof对其它函数进行记录。

运行

编译好的程序运行时和运行一般的程序没有什么不同,只是比正常的程序多生成了一个文件gmon.out。注意,这个文件名是固定的,没法通过参数的设置进行改变。如果程序目录中已经有一个gmon.out,则它会被新的gmon.out覆盖掉。

关于生成的gmon.out文件所在的目录,也有以下约定:程序退出时所运行的文件所在目录就是生成的gmon.out文件所在的目录。如果一个程序执行过程中调用了另一个程序,并在另一个程序的运行中终止,则gmon.out会在另一个程序所在的目录中生成。

还有一点要注意的就是当程序非正常终止时不会生成gmon.out文件,也因此就没法查看程序运行时的信息。只有当程序从main函数中正常退出,或者通过系统调用exit()函数而退出时,才会生成gmon.out文件。而通过底层调用如_exit()等退出时不会生成gmon.out。

查看

查看程序运行信息的命令是gprof,它以gmon.out文件作为输入,也就是将gmon.out文件翻译成可读的形式展现给用户。其命令格式如下:

gprof [可执行文件] [gmon.out文件] [其它参数]

方括号中的内容可以省略。如果省略了“可执行文件”,gprof会在当前目录下搜索a.out文件作为可执行文件,而如果省略了gmon.out文件,gprof也会在当前目录下寻找gmon.out。其它参数可以控制gprof输出内容的格式等信息。最常用的参数如下:

l         -b 不再输出统计图表中每个字段的详细描述。

l         -p 只输出函数的调用图(Call graph的那部分信息)。

l         -q 只输出函数的时间消耗列表。

l         -e Name 不再输出函数Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志。一个 -e 标志只能指定一个函数。

l         -E Name 不再输出函数Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数Name 及其子函数所用的时间。

l         -f Name 输出函数Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。

l         -F Name 输出函数Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。

l         -z 显示使用次数为零的例程(按照调用计数和累积时间计算)。

不过,gprof不能显示对象之间的继承关系,这也是它的弱点.

gprof 实现原理
gprof并不神奇,在编译和链接程序的时候(使用 -pg 编 译和链接选项),gcc 在你应用程序的每个函数中都加入了一个名为mcount(or“_mcount”, or“__mcount”) 的函数,也就是说-pg编译的应用程序里的每一个函数都会调用mcount, 而mcount会在内存中保存一张函数 调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信息。

程序分析工具gprof介绍相关推荐

  1. 性能分析工具gprof介绍

    Ver:1.0 目录 1. GPROF介绍 4 2. 使用步骤 4 3. 使用举例 4 3.1 测试环境 4 3.2 测试代码 4 3.3 数据分析 5 3.3.1 flat profile模式 6 ...

  2. Windows系统内存分析工具的介绍

    Windows系统内存分析工具的介绍(进程管理器,资源管理器,性能监视器, VMMap, RamMap,PoolMon) 微软官方提供多种工具来分析Windows 的内存使用情况,除了系统自带的任务管 ...

  3. linux程序分析工具下载,linux 程序分析工具

    http://blog.csdn.net/denny_233/article/details/7477282 2012 linux程序分析工具介绍(一)--"/proc" 写在最前 ...

  4. golang性能分析工具pprof介绍

    1 golang性能分析工具pprof介绍 文章目录 1 golang性能分析工具pprof介绍 1.1 pprof简介 1.2 pprof引入方法 1.3 使用pprof进行分析的方法 1.3.1 ...

  5. 程序崩溃 分析工具_程序分析工具| 软件工程

    程序崩溃 分析工具 A program analysis tool implies an automatic tool that takes the source code or the execut ...

  6. mcq 队列_MCQ | 软件程序分析工具和组件分类| 免费和开源软件

    mcq 队列 Q1. Which of the following analysis methods come under Static Analysis Tools? Q1. 静态分析工具包含以下哪 ...

  7. java 复杂网络分析_基于复杂网络的Java程序分析工具设计与实现思路浅谈

    基于复杂网络的Java程序分析工具设计与 实现思路浅谈 摘要:近年来,随着科学技术的进步,计算机技术发展速度的加快,使得软件价值也逐步提高,不管是软件系统的应用领域,还是其规模均获得了相应的扩大,且软 ...

  8. linux程序测试工具gprof,gprof-如何在Linux上分析多线程C ++应用程序?

    gprof-如何在Linux上分析多线程C ++应用程序? 我曾经使用gprof进行所有Linux分析. 但是,对于我的多线程应用程序,它的输出似乎不一致. 现在,我将其挖掘出来: [HTTP://S ...

  9. 猿如意中的【Wireshark】网络包分析工具详情介绍

    一.工具名称 Wireshark-win64-3.6.5 二.下载安装渠道 Wireshark-win64-3.6.5 通过CSDN官方开发的[猿如意]客户端进行下载安装. 对,你没有看错,就是来自C ...

最新文章

  1. 【待继续研究】解析信用评分模型的开发流程及检验标准(晕乎乎,看不懂~)
  2. JVM-04垃圾收集Garbage Collection(上)【垃圾对象的判定】
  3. 开源网站云查杀方案,搭建自己的云杀毒。
  4. Hangover C语言 UVA2294
  5. 三维点云学习(4)1- Spectral的理论推导与解释
  6. 分享一些前端优质的掘金小册,学完技术感觉已经超神了
  7. 国美金融贷款Kube-apiserver源码分析(国美金融贷款)
  8. 关于Release版除法反汇编的小结
  9. 您需要administrator权限才能对此文件进行更改
  10. STM32延时函数的四种方法
  11. 在线组态工具 html,组态工具-界面组件
  12. 微信ios浏览器 与 iframe的不兼容问题
  13. 最新计算机java毕业设计选题题目推荐
  14. 小程序微信支付提示:商户订单号重复
  15. python爬知乎_python爬行求知。,爬取,知乎,精华
  16. 嵌入式系统(五):RISC-V4
  17. Android开发推荐资料大合集 【转载自51CTO】
  18. 丰田生产方式的浪费观——《可以量化的管理学》
  19. 如何共享本地打印机,如何共享他人打印机
  20. python金融数据缺失处理_顺利迈过Tushare+python3+mySql读取金融数据的坑

热门文章

  1. ios开发 微博图片缩放处理错误_H5响应式开发必会之Viewport(视窗)详解
  2. basequickadapter详解_在kotlin中如何使用BaseQuickAdapter适配器
  3. end-to-end 的神经网络
  4. Python Qt GUI设计:QTableView、QListView、QListWidet、QTableWidget、QTreeWidget和QTreeWidgetltem表格和树类(提升篇—1)
  5. 【从零开始的ROS四轴机械臂控制】(四)- ros、gazebo与opencv,图像处理节点
  6. 【骚气的动效】外发光涟漪波纹动画、向外辐射动画效果,通常用于地图上面某一个扩散点效果
  7. 在Ubuntu 14.04和CentOS上安装boost1.55二进制包
  8. 读书:个人成长 -- 即兴演讲
  9. 全国所有省市县地理坐标Json格式
  10. ●洛谷P3688 [ZJOI2017]树状数组