調試工具-gprof

gprof

1.1      簡介

gprof實際上只是一個用於讀取profile結果文件的工具。gprof採用混合方法來收集程序的統計信息,他使用檢測方法,在編譯過程當中在函數入口處插入計數器用於收集每一個函數的被調用狀況和被調用次數;也使用採樣方法,在運行時按必定間隔去檢查程序計數器並在分析時找出程序計數器對應的函數來統計函數佔用的時間。css

 

Gprof具備如下優缺點:多線程

 

1)  優勢:app

a)         GNU工具,人手一個;函數

b)        混合方法採集信息。工具

 

2)  缺點:性能

a)         須要編譯選項支持:測試

             i.              使用gcc/cc編譯和連接時須要加入-pg選項優化

             ii.              使用ld連接時須要用/lib/gcrt0.o代替crt0.o做爲第一個input文件this

             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文件。
相關文章
相關標籤/搜索