提供
- 1.程序运行的“flat profile”,包括每个函数的调用次数,每个函数消耗的处理器时间。
- 2.“调用图”,包括函数的调用关系,每个函数调用花费了多少时间。
- 3.“注释的源代码”,是程序源代码的一个复本,标记有程序中每行代码的执行次数。
用法
- 1.使用-pg选项编译和链接你的应用程序。
- 2.执行你的应用程序,使之运行完成后生成供gprof分析的数据文件(默认是gmon.out)。
- 3.使用gprof程序分析你的应用程序生成的数据,例如:gporf a.out gmon.out。
示例
- gcc -Wall -pg -o test test.c //程序文件名称 test.c 编译时使用 -pg
- ./test //现在可以再次运行test,并使用前面使用的测试数据
- //这次运行时,test运行的分析数据会被搜集并保存在'gmon.out'文件中
- gprof test //可以通过运行 ' gprof test '来查看结果。
原理
- gprof,在编译和链接程序的时 候(使用 -pg 编译和链接选项),gcc 在你应用程序的每个函数中都加入了一个名为mcount(or“_mcount”, or“__mcount”)的函数,
- 也就是说-pg编译的应用程序里的每一个函数都会调用mcount, 而mcount会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信息。
- 程序运行结束后,会在程序退出的路径下生成一个 gmon.out文件。这个文件就是记录并保存下来的监控数据。可以通过命令行方式的gprof或图形化的Kprof来解读这些数据并对程序的性能进行分析。
- 另外,如果想查看库函数的profiling,需要在编译是再加入“-lc_p”编译参数代替“-lc”编译参数,这样程序会链接libc_p.a 库,才可以产生库函数的profiling信息。如果想执行一行一行的profiling,还需要加入“-g”编译参数。
缺点
- 1.调试多线程程序只能统计主线程的信息
- 2.不能用于调试后台进程
- 3.只有正常退出时才能产生gmon.out文件
对缺点3.的说明
- 原因是gprof通过在atexit()里注册了一个函数来产生结果信息,任何非正常退出都不会执行atexit()的动作,所以不会产生gmon.out文件。
- 如果你的程序是一个不会退出的服务程序,那就只有修改代码来达到目的。如果不想改变程序的运行方式,可以添加一个信号处理函数解决问题(这样对代码修改最少),例如:
- static void sighandler( int sig_no )
- {
- exit(0);
- }
- signal( SIGUSR1, sighandler );
- 当使用kill -USR1 pid 后,程序退出,生成gmon.out文件。
输出项说明
- % 函数使用时间占所有时间的百分比
- cumulative 函数和上列函数累计执行的时间(seconds)
- self 函数本身所执行的时间(seconds)
- calls 函数被调用的次数
- self ms/call 每一次调用花费在函数的时间microseconds。
- total ms/call 每一次调用,花费在函数及其衍生函数的平均时间microseconds。
- name 函数名