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" 命令行里面輸入下面命令,沒加-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 你會在當(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 從上面的輸出我們能明顯的看出來,main 調(diào)用了 b 函數(shù), 而b 函數(shù)分別調(diào)用了a 和 c 函數(shù)。由于我們的函數(shù)只是簡單的輸出了一個字串,故每個函數(shù)的消耗時間都是0 秒。 常用的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 如果沒有出錯你會在/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你就知道了那個函數(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 { 要將這個 .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等等。
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文件即可:
總結(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/ |
|