zoukankan      html  css  js  c++  java
  • 转- C调试方法之--------Gprofile

    一、GProfile简介

          GProfile是gcc的一个工具,用于对应用程序的测试。

          GProfile可以分析出函数的调用次数、函数的调用关系以及函数消耗的时间。

     

    二、GProfile原理

          在 编译和链接你的程序的时候,gcc 在你应用程序的每个函数中都加入了一个名为mcount ( or "_mcount" , or "__mcount" , 依赖于编译器或操作系统)的函数,也就是说你的应用程序里的每一个函数都会调用mcount, 而mcount 会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信 息。 

         程序运行结束后,会在程序退出的路径下生成一个gmon.out文件,用来保存监控数据。从而通过gprof来解读数据对程序进行分析。

              

    三、GProfile用法

          1、在编译时加入参数 -pg就可以打开GProfile的开关。

          2、gprof只查看用户函数信息,不能对库函数进行查看。 如果想查看库函数的信息,在编译时加入"-lc_p"编译参数代替"-lc"编译参数,这样程序会链接libc_p.a库,就可以查看库函数的信息了。 
      3、 gprof只能在程序正常结束退出之后才能生成程序测评报告,原因是gprof通过在atexit()里注册了一个函数来产生结果信息,任何非正常退出都 不会执行atexit()的动作,所以不会产生gmon.out文件。如果你的程序是一个不会退出的服务程序,那就只有修改代码来达到目的。如果不想改变 程序的运行方式,可以添加一个信号处理函数解决问题(这样对代码修改最少),例如: 
      static void sighandler( int sig_no ) 
      { 
      exit(0); 
      } 
      signal( SIGUSR1, sighandler ); 
      当使用kill -USR1 pid 后,程序退出,生成gmon.out文件。 

     

    四、GProfile举例

       

    #include <stdio.h>
      int ppp(int a)
      {
         int i, b;
         b = 0;
         for(i = 0; i<1000000; i++) {
            b++;
         }
         return 0;
      }

     

      int prime(int n)
      {
         int i, j, b;
         b = 0;
         for(i=2; i<n; i++) {
             for(j = 0; j<1000000; j++) {
                  b++;
             }
             if(n%i == 0)
               return 0;
             return 1;
            }
       }

     

       int main(void)
       {
          int i, n;
          n = 1000;
          for(i=2; i<=n; i++) {
             if(prime(i)) {
                ppp(i);
             }
          }
          return 0;
       }

     

       编译程序:gcc -pg -o test test.c
      运行源程序./test后会生成一个gmon.out的文件。
       分析结果:gprof -b test gmon.out
     

      

     五、GProfile对于结果的分析

          -b 不再输出统计图表中每个字段的详细描述。 
      -p 只输出函数的调用图(Call graph的那部分信息)。 
      -q 只输出函数的时间消耗列表。 
      -e Name 不再输出函数Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志。一个 -e 标志只能指定一个函数。 
      -E Name 不再输出函数Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数Name 及其子函数所用的时间。 
      -f Name 输出函数Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。 
      -F Name 输出函数Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。 
      -z 显示使用次数为零的例程(按照调用计数和累积时间计算)。 

          GProfile的详细请参考:http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html

          这个文档对GProfile说的很详细,很好。

  • 相关阅读:
    关于js计算非等宽字体宽度的方法
    [NodeJs系列]聊一聊BOM
    Vue.js路由管理器 Vue Router
    vue 实践技巧合集
    微任务、宏任务与Event-Loop
    事件循环(EventLoop)的学习总结
    Cookie、Session和LocalStorage
    MySQL 树形结构 根据指定节点 获取其所在全路径节点序列
    MySQL 树形结构 根据指定节点 获取其所有父节点序列
    MySQL 创建函数报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators
  • 原文地址:https://www.cnblogs.com/myyan/p/4235362.html
Copyright © 2011-2022 走看看