• 调试工具-gprof


    gprof

    1.1      简介

    gprof实际上只是一个用于读取profile结果文件的工具。gprof采用混合方法来收集程序的统计信息,他使用检测方法,在编译过程中在函数入口处插入计数器用于收集每个函数的被调用情况和被调用次数;也使用采样方法,在运行时按一定间隔去检查程序计数器并在分析时找出程序计数器对应的函数来统计函数占用的时间。

    Gprof具有以下优缺点:

    1)  优点:

    a)         GNU工具,人手一个;

    b)        混合方法采集信息。

    2)  缺点:

    a)         需要编译选项支持:

                 i.              使用gcc/cc编译和链接时需要加入-pg选项

                 ii.              使用ld链接时需要用/lib/gcrt0.o代替crt0.o作为第一个input文件

                 iii.              如果要调试libc库需要使用-lc_p代替-lc参数

    b)        调试多线程程序只能统计主线程的信息(所以不能用于kingbase)。

    1.2      使用方法

    1.2.1        编译程序

    使用gcc/cc编译和链接时需要加入-pg选项

    使用ld链接时需要用/lib/gcrt0.o代替crt0.o作为第一个input文件

    如果要调试libc库需要使用-lc_p代替-lc参数

    1.2.2        运行程序生成统计信息

    正常运行编译好的程序,程序正常结束后会在当前目录生成统计信息文件gmon.out。

    程序必须正常退出(调用exit或从main中返回)才能生成统计信息。

    当前目录下如果有另外叫gmon.out的文件,内容将被本次运行生成的统计信息覆盖,多次运行统一程序请将前一次的gmon.out改名。

    1.2.3        使用gprof查看统计结果

    命令格式:

    gprof options [executable-file [profile-data-files...]] [> outfile]

    常用参数介绍:

    symspec表示需要加入或排除的函数名,和gdb指定断点时的格式相同。

    1)  输出相关:

    a)         -A[symspec]或--annotated-source[=symspec]:进行源码关联,只关联symspec指定的函数,不指定为全部关联。

    b)        -I dirs或--directory-path=dirs:添加搜索源码的文件夹,修改环境变量GPROF_PATH也可以。

    c)         -p[symspec]或--flat-profile[=symspec]:默认选项,输出统计信息,只统计symspec指定的函数,不指定为全部统计。

    d)        -P[symspec]或--no-flat-profile[=symspec]:排除统计symspec指定的函数

    e)         -q[symspec]或--graph[=symspec]:默认选项,输出函数调用信息,只统计symspec指定的函数,不指定为全部统计。

    f)         -Q[symspec]或--no-graph[=symspec]:排除统计symspec指定的函数

    g)        -b或--brief:不输出对各个参数含义的解释;

    2)  分析相关:

    a)         -a或--no-static:定义为static的函数将不显示,函数的被调用次数将被计算在调用它的不是static的函数中;

    b)        -m num或--min-count=num:不显示被调用次数小于num的函数;

    c)         -z或--display-unused-functions:显示没有被调用的函数;

    1.3      一个例子

    编译测试文件:

    gcc –g –o test test.c –pg

    执行程序:

    ./test

    查看统计信息:

    gprof -b -A -p -q test gmon.out > pg

    1.4      gprof产生的信息解析

     %                        the percentage of the total running time of the
    time                     program used by this function.
                               函数使用时间占所有时间的百分比。
    cumulative          a running sum of the number of seconds accounted
     seconds             for by this function and those listed above it.
                               函数和上列函数累计执行的时间。
     self                    the number of seconds accounted for by this
    seconds             function alone.  This is the major sort for this
                              listing.
                              函数本身所执行的时间。
    calls                   the number of times this function was invoked, if
                              this function is profiled, else blank.
                              函数被调用的次数
     self                   the average number of milliseconds spent in this
    ms/call               function per call, if this function is profiled,
                             else blank.
                              每一次调用花费在函数的时间microseconds。
     total                  the average number of milliseconds spent in this
    ms/call               function and its descendents per call, if this 
                              function is profiled, else blank.
                              每一次调用,花费在函数及其衍生函数的平均时间microseconds。
    name                 the name of the function.  This is the minor sort
                              for this listing. The index shows the location of
                              the function in the gprof listing. If the index is
                              in parenthesis it shows where it would appear in
                              the gprof listing if it were to be printed.
                              函数名

    1.4      结论

    我们可以使用程序概要分析快速的找到一个程序里面值得优化的地方。

    1. 1.5    原理

    2. gprof,在编译和链接程序的时 候(使用 -pg 编译和链接选项),gcc 在你应用程序的每个函数中都加入了一个名为mcount(or“_mcount”, or“__mcount”)的函数,
    3. 也就是说-pg编译的应用程序里的每一个函数都会调用mcount, 而mcount会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信息。
    4. 程序运行结束后,会在程序退出的路径下生成一个 gmon.out文件。这个文件就是记录并保存下来的监控数据。可以通过命令行方式的gprof或图形化的Kprof来解读这些数据并对程序的性能进行分析。
    5. 另外,如果想查看库函数的profiling,需要在编译是再加入“-lc_p”编译参数代替“-lc”编译参数,这样程序会链接libc_p.a 库,才可以产生库函数的profiling信息。如果想执行一行一行的profiling,还需要加入“-g”编译参数。

    1.5    缺点

    1. 1.调试多线程程序只能统计主线程的信息
    2. 2.不能用于调试后台进程
    3. 3.只有正常退出时才能产生gmon.out文件
    对缺点3.的说明
    1. 原因是gprof通过在atexit()里注册了一个函数来产生结果信息,任何非正常退出都不会执行atexit()的动作,所以不会产生gmon.out文件。
    2. 如果你的程序是一个不会退出的服务程序,那就只有修改代码来达到目的。如果不想改变程序的运行方式,可以添加一个信号处理函数解决问题(这样对代码修改最少),例如:
    3. static void sighandler( int sig_no )
    4. {
    5. exit(0);
    6. }
    7. signal( SIGUSR1, sighandler );
    8. 当使用kill -USR1 pid 后,程序退出,生成gmon.out文件。
  • 相关阅读:
    fmri资源站点
    spm教程
    linux下ntfs硬盘的加载
    Unix网络编程代码 第13章 守护进程和inetd超级服务器
    APUE16章的运行示例16-14
    Linux守护进程详解(init.d和xinetd)
    centos安装g++
    linux下daemon守护进程的实现(以nginx代码为例)
    Linux进程学习(孤儿进程和守护进程)
    Linux之TCPIP内核参数优化
  • 原文地址:https://www.cnblogs.com/moon-in-sky/p/3245498.html
Copyright © 2020-2023  润新知