乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      使用Gnu gprof進(jìn)行Linux平臺下的程序分析

       開花結(jié)果 2010-04-29
      Gprof 簡介:

      Gprof功能:打印出程序運行中各個函數(shù)消耗的時間,可以幫助程序員找出眾多函數(shù)中耗時最多的函數(shù)。產(chǎn)生程序運行時候的函數(shù)調(diào)用關(guān)系,包括調(diào)用次數(shù),可以幫助程序員分析程序的運行流程。

      有了函數(shù)的調(diào)用關(guān)系,這會讓開發(fā)人員大大提高工作效率,不用費心地去一點點找出程序的運行流程,這對小程序來說可能效果不是很明顯,但對于有幾萬,幾十萬代碼量的工程來說,效率是毋庸置疑的!而且這個功能對于維護(hù)舊代碼或者是分析Open Source來說那是相當(dāng)誘人的,有了調(diào)用圖,對程序的運行框架也就有了一個大體了解,知道了程序的“骨架“,分析它也就不會再那么茫然,尤其是對自己不熟悉的代碼和Open Source。費話不多說了,讓我們開始我們的分析之旅吧!

      Gprof 實現(xiàn)原理:

      通過在編譯和鏈接你的程序的時候(使用 -pg 編譯和鏈接選項),gcc 在你應(yīng)用程序的每個函數(shù)中都加入了一個名為mcount ( or “_mcount” , or “__mcount” , 依賴于編譯器或操作系統(tǒng))的函數(shù),也就是說你的應(yīng)用程序里的每一個函數(shù)都會調(diào)用mcount, 而mcount 會在內(nèi)存中保存一張函數(shù)調(diào)用圖,并通過函數(shù)調(diào)用堆棧的形式查找子函數(shù)和父函數(shù)的地址。這張調(diào)用圖也保存了所有與函數(shù)相關(guān)的調(diào)用時間,調(diào)用次數(shù)等等的所有信息。

      Gprof基本用法:

      1. 使用 -pg 編譯和鏈接你的應(yīng)用程序。

      2. 執(zhí)行你的應(yīng)用程序使之生成供gprof 分析的數(shù)據(jù)。

      3. 使用gprof 程序分析你的應(yīng)用程序生成的數(shù)據(jù)。

      Gprof 簡單使用:

      讓我們簡單的舉個例子來看看Gprof是如何使用的。

      1.打開linux終端。新建一個test.c文件,并生用-pg 編譯和鏈接該文件。 test.c 文件內(nèi)容如下:
      Quote:
      #include "stdio.h"

      #include "stdlib.h"



      void a(){

      printf("\t\t+---call a() function\n");

      }



      void c(){

      printf("\t\t+---call c() function\n");

      }



      int b(){

      printf("\t+--- call b() function\n");

      a();

      c();

      return 0;

      }

      int main(){

      printf(" main() function()\n");

      b();

      }



      命令行里面輸入下面命令,沒加-c選項,gcc 會默認(rèn)進(jìn)行編譯并鏈接生成a.out:
      Quote:
      [linux /home/test]$gcc -pg test.c



      如果沒有編譯錯誤,gcc會在當(dāng)前目錄下生成一個a.out文件,當(dāng)然你也可以使用 –o 選項給生成的文件起一個別的名字,像 gcc –pg test.c –o test , 則gcc會生成一個名為test的可執(zhí)行文件,在命令行下輸入[linux /home/test]$./test , 就可以執(zhí)行該程序了,記住一定要加上 ./ 否則程序看上去可能是執(zhí)行,可是什么輸出都沒有。

      2.執(zhí)行你的應(yīng)用程序使之生成供gprof 分析的數(shù)據(jù)。 命令行里面輸入:
      Quote:
      [linux /home/test]$a.out

      main() function()

      +--- call b() function

      +---call a() function

      +---call c() function

      [linux /home/test]$

      你會在當(dāng)前目錄下看到一個gmon.out 文件, 這個文件就是供gprof 分析使用的。

      3.使用gprof 程序分析你的應(yīng)用程序生成的數(shù)據(jù)。

      命令行里面輸入:
      Quote:
      [linux /home/test]$ gprof -b a.out gmon.out | less

      由于gprof輸出的信息比較多,這里使用了 less 命令,該命令可以讓我們通過上下方向建查看gprof產(chǎn)生的輸出,| 表示gprof -b a.out gmon.out 的輸出作為 less的輸入。下面是我從gprof輸出中摘抄出的與我們有關(guān)的一些詳細(xì)信息。
      Quote:
      % cumulative self self total

      time seconds seconds calls Ts/call Ts/call name

      0.00 0.00 0.00 1 0.00 0.00 a

      0.00 0.00 0.00 1 0.00 0.00 b

      0.00 0.00 0.00 1 0.00 0.00 c

      Call graph

      granularity: each sample hit covers 4 byte(s) no time propagated

      index % time self children called name

      0.00 0.00 1/1 b [2]

      [1] 0.0 0.00 0.00 1 a [1]

      -----------------------------------------------

      0.00 0.00 1/1 main [10]

      [2] 0.0 0.00 0.00 1 b [2]

      0.00 0.00 1/1 a [1]

      0.00 0.00 1/1 c [3]

      -----------------------------------------------

      0.00 0.00 1/1 b [2]

      [3] 0.0 0.00 0.00 1 c [3]

      從上面的輸出我們能明顯的看出來,main 調(diào)用了 b 函數(shù), 而b 函數(shù)分別調(diào)用了a 和 c 函數(shù)。由于我們的函數(shù)只是簡單的輸出了一個字串,故每個函數(shù)的消耗時間都是0 秒。

      gprof產(chǎn)生的信息解釋如下:

      使用Gnu gprof進(jìn)行Linux平臺下的程序分析(圖一)
      gprof產(chǎn)生的信息解釋
       
      常用的Gprof 命令選項解釋:

      -b不再輸出統(tǒng)計圖表中每個字段的詳細(xì)描述。

      -p 只輸出函數(shù)的調(diào)用圖(Call graph 的那部分信息)。

      -q 只輸出函數(shù)的時間消耗列表。

      -E Name不再輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖,此標(biāo)志類似于 -e 標(biāo)志,但它在總時間和百分比時間的計算中排除了由函數(shù)Name 及其子函數(shù)所用的時間。

      -e Name 不再輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖(除非它們有未被限制的其它父函數(shù))??梢越o定多個 -e 標(biāo)志。一個 -e 標(biāo)志只能指定一個函數(shù)。

      -F Name 輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖,它類似于 -f 標(biāo)志,但它在總時間和百分比時間計算中僅使用所打印的例程的時間??梢灾付ǘ鄠€ -F 標(biāo)志。一個 -F 標(biāo)志只能指定一個函數(shù)。-F 標(biāo)志覆蓋 -E 標(biāo)志。

      -f Name輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖??梢灾付ǘ鄠€ -f 標(biāo)志。一個 -f 標(biāo)志只能指定一個函數(shù)。

      -z 顯示使用次數(shù)為零的例程(按照調(diào)用計數(shù)和累積時間計算)。

      到這為止你可能對gprof 有了一個比較感性的認(rèn)識了,你可能會問如何用它去分析一個真正的Open Source 呢!下面就讓我們?nèi)ビ胓prof去分析一個Open Source,看看如何去在真實的環(huán)境中使用它。

      使用Gprof 分析 Cflow開源項目

      CFlow 是程序流程分析工具,該工具可以通過分析C源代碼,產(chǎn)生程序調(diào)用圖!有點跟Gprof差不多,不過CFlow是通過源代碼進(jìn)行的靜態(tài)分析并且 不能分析C++ 程序,你可以到http://www./software/cflow/去下載源代碼。

      假設(shè)你已經(jīng)下載了該源代碼(cflow-1.1.tar.gz),并把它放置在/home目錄下,讓我們看看如何在這個應(yīng)用上使用gprof。

      1. 使用 -pg 編譯和鏈接該應(yīng)用程序,請輸入下列命令。
      Quote:
      [linux /home/]tar zxvf cflow-1.1.tar.gz

      [linux /home/cflow-1.1/src]$./configure

      [linux /home]$make CFLAGS=-pg LDFLAGS=-pg

      如果沒有出錯你會在/home/cflow-1.1/src 目錄下發(fā)行一個名為cflow的可執(zhí)行文件,這就是我們加入-pg編譯選項后編譯出來的可以產(chǎn)生供gprof提取信息的可執(zhí)行文件。記住一定要在編譯和鏈接的時候都使用-pg選項,否則可能不會產(chǎn)生gmon.out文件。對于cflow項目,CFLAGS=-pg 是設(shè)置它的編譯選項,LDFLAGS=-pg是設(shè)置它的鏈接選項。當(dāng)然你也可以直接修改它的Makefile來達(dá)到上述相同的目的,不過一定要記住編譯和鏈接都要使用-pg選項。

      2. 運行cflow 程序使之生成gmon.out 文件供gprof使用。
      Quote:
      [linux /home/cflow-1.1/src]$cflow parser.c

      查看/home/cflow-1.1/src目錄下有沒有產(chǎn)生gmon.out文件,如果沒有請重復(fù)第一步,并確認(rèn)你已經(jīng)在編譯和鏈接程序的時候使用了-pg 選項。Cflow的使用請參考http://www./software/cflow/manual/cflow.html

      3. 使用gprof分析程序

      [linux /home/cflow-1.1/src]$gprof -b cflow gmon.out | less

      恭喜你,不出意外你會在屏幕上看到gprof的輸出,函數(shù)消耗時間和函數(shù)調(diào)用圖,下面是我從我的輸出中摘抄出來的一小段。
      Quote:
      % cumulative self self total

      time seconds seconds calls Ts/call Ts/call name

      0.00 0.00 0.00 118262 0.00 0.00 include_symbol

      0.00 0.00 0.00 92896 0.00 0.00 is_printable

      0.00 0.00 0.00 28704 0.00 0.00 set_level_mark

      0.00 0.00 0.00 28703 0.00 0.00 is_last

      0.00 0.00 0.00 19615 0.00 0.00 auto_processor

      0.00 0.00 0.00 15494 0.00 0.00 gnu_output_handler

      0.00 0.00 0.00 12286 0.00 0.00 delete_parm_processor

      0.00 0.00 0.00 7728 0.00 0.00 newline

      0.00 0.00 0.00 7728 0.00 0.00 print_function_name

      0.00 0.00 0.00 7728 0.00 0.00 print_level

      。。。。。。

      。。。。。。

      Call graph

      granularity: each sample hit covers 4 byte(s) no time propagated

      index % time self children called name

      [1] 0.0 0.00 0.00 79+855 [1]

      0.00 0.00 166 dcl [52]

      0.00 0.00 163 parse_dcl [53]

      0.00 0.00 150 dirdcl [56]

      0.00 0.00 129 parse_declaration [63]

      0.00 0.00 98 parse_variable_declaration [66]

      0.00 0.00 63 maybe_parm_list [69]

      0.00 0.00 63 parse_function_declaration [70]

      0.00 0.00 39 func_body [74]

      。。。。。。

      。。。。。。

      通過分析%time你就知道了那個函數(shù)消耗的時間最多,你可以根據(jù)這個輸出信息做有目的的優(yōu)化,不過cflow執(zhí)行的速度是在是太快了,以至%time都是0 (消耗時間是以秒為單位進(jìn)行統(tǒng)計的)。
       
      生成圖形化的函數(shù)調(diào)用圖

      1.Graphviz 工具

      看到這里你也可能覺得上面的函數(shù)調(diào)用圖實在是不方便察看,也看不出來一個程序調(diào)用的整體框架。沒有關(guān)系,我再介紹一個有用的工具給你,使用 Graphviz,Graphviz or Graph Visualization 是由 AT&T 開發(fā)的一個開源的圖形可視化工具。它提供了多種畫圖能力,但是我們重點關(guān)注的是它使用 Dot 語言直連圖的能力。在這里,將簡單介紹如何使用 Dot 來創(chuàng)建一個圖形,并展示如何將分析數(shù)據(jù)轉(zhuǎn)換成 Graphviz 可以使用的規(guī)范, Dot 使用的圖形規(guī)范。

      使用 Dot 語言,你可以指定三種對象:圖、節(jié)點和邊。為了讓你理解這些對象的含義,我將構(gòu)建一個例子來展示這些元素的用法。

      下圖給出了一個簡單的定向圖(directed graph),其中包含 3 個節(jié)點。第一行聲明這個圖為 G,并且聲明了該圖的類型(digraph)。接下來的三行代碼用于創(chuàng)建該圖的節(jié)點,這些節(jié)點分別名為 node1、node2 和 node3。節(jié)點是在它們的名字出現(xiàn)在圖規(guī)范中時創(chuàng)建的。邊是在在兩個節(jié)點使用邊操作(->)連接在一起時創(chuàng)建的,如第 6 行到第 8 行所示。我還對邊使用了一個可選的屬性 label,用它來表示邊在圖中的名稱。最后,在第 9 行完成對該圖規(guī)范的定義。

      使用 Dot 符號表示的示例圖(test.dot)
      Quote:
      1: digraph G {

      2: node1;

      3: node2;

      4: node3;

      5:

      6: node1 -> node2 [label="edge_1_2"];

      7: node1 -> node3 [label="edge_1_3"];

      8: node2 -> node3 [label="edge_2_3"];

      9: }


      要將這個 .dot 文件轉(zhuǎn)換成一個圖形映像,則需要使用 Dot 工具,這個工具是在 Graphviz 包中提供的。清單 6 介紹了這種轉(zhuǎn)換。

      清單 6. 使用 Dot 來創(chuàng)建 JPG 映像

      [linux /home]$ dot -Tjpg test.dot -o test.jpg

      在這段代碼中,我告訴 Dot 使用 test.dot 圖形規(guī)范,并生成一個 JPG 圖像,將其保存在文件 test.jpg 中。所生成的圖像如圖1所示。在此處,我使用了 JPG 格式,但是 Dot 工具也可以支持其他格式,其中包括 GIF、PNG 和 postscript等等。
      使用Gnu gprof進(jìn)行Linux平臺下的程序分析(圖二)
      圖 1. Dot 創(chuàng)建的示例圖


      Dot 語言還可以支持其他一些選項,包括外形、顏色和很多屬性。有興趣可以查看graphviz相關(guān)文檔。

      2.從gprof的輸出中提取調(diào)用圖信息,產(chǎn)生可供Graphviz使用的dot文件。

      這樣的腳本有人已經(jīng)實現(xiàn)了,我們只要下載一個現(xiàn)成的就可以了,首先從http://www./~miallen/ 網(wǎng)站下載一個mkgraph腳本。解壓該腳本到包含gmon.out文件的目錄下。使用mkgraph0.sh產(chǎn)生調(diào)用的jpg圖像文件。例如:使用上面的例子,生成cflow的調(diào)用圖。

      [linux /home/cflow-1.1/src]$ mkgraph0.sh cflow gmon.out

      部分調(diào)用圖如下,有了這個圖是不是對程序整體框架有了個清晰地了解,如果你對生成的調(diào)用圖效果不滿意,你還可以通過修改mkgraph0腳本使之產(chǎn)生合適的dot文件即可:

      使用Gnu gprof進(jìn)行Linux平臺下的程序分析(圖三)
      部分調(diào)用圖如下


      總結(jié):

      使用gprof , Graphviz , mkgraph 生成函數(shù)調(diào)用圖

      1. 使用 -pg 編譯和鏈接你的應(yīng)用程序。

      2. 執(zhí)行你的應(yīng)用程序使之生成供gprof 分析的數(shù)據(jù)。

      3. 使用mkgraph腳本生成圖形化的函數(shù)調(diào)用圖。

      相關(guān)資料:

      文檔:用 Graphviz 可視化函數(shù)調(diào)用

      文檔:Speed your code with the GNU profiler

      文檔:gropf 幫助文件

      Mkgraph 腳本:http://www./~miallen/

      Graphviz 工具:http://www.

      Cflow         :http://www./software/cflow/
       
      這個工具確實相當(dāng)有用,尤其是閱讀源代碼。

      在分析內(nèi)核源代碼的時候,有一個和gprof類似的工具,叫KFT(kernel function trace),也可以用來生成內(nèi)核函數(shù)的調(diào)用圖,以及分析各種時間關(guān)系等。

      因此,綜合這兩個工具就可以非常方便的閱讀和分析內(nèi)核態(tài)和應(yīng)用態(tài)的程序拉。

      其實在gdb里頭也可以用bt命令生成當(dāng)前函數(shù)的被調(diào)用關(guān)系圖,不過在調(diào)試gdb本身的時候,似乎得需要gprof的幫助拉,因為被調(diào)試的gdb沒有辦法擁有它自身的交互模式用以執(zhí)行那些交互命令。

      [1] KFT的網(wǎng)站:http://tree./CelfPubWiki/KernelFunctionTrace
      附件里頭有我寫的一個自動進(jìn)行KFT分析的腳本(有待優(yōu)化,最新版本請關(guān)注我的首頁http://dslab./members/falcon
      [2] Call Graph Drawing Interface Page(for gprof,貌似Makefile文件和vco有點問題,用的時候注意一下[falcon補(bǔ)充])
      http://www.ida./~vaden/cgdi/
      [3] CodeViz - A call graph generation utility for C/C++
      http://www.csn./~mel/projects/codeviz/

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多