程序分析工具gprof介绍
程序分析工具不同于調(diào)試器,它只產(chǎn)生程序運(yùn)行時某些函數(shù)的調(diào)用次數(shù)、執(zhí)行時間等等宏觀信息,而不是每條語句執(zhí)行時的詳細(xì)信息。Gprof是Linux下一個強(qiáng)有力的程序分析工具。對于C、Pascal或者Fortran77語言的程序,它能夠以“日志”的形式記錄程序運(yùn)行時的統(tǒng)計信息:程序運(yùn)行中各個函數(shù)消耗的時間和函數(shù)調(diào)用關(guān)系,以及每個函數(shù)被調(diào)用的次數(shù)等等。從而可以幫助程序員找出眾多函數(shù)中耗時最多的函數(shù),也可以幫助程序員分析程序的運(yùn)行流程。相信這些功能對于分析開源代碼的程序員來說,有著相當(dāng)大的誘惑力。
用gprof分析程序
用gprof對程序進(jìn)行分析主要分以下三個步驟:
l???????? 用編譯器對程序進(jìn)行編譯,加上-pg參數(shù)。
l???????? 運(yùn)行編譯后的程序。
l???????? 用gprof命令查看程序的運(yùn)行時信息。
先以一個簡單的例子演示一下吧。隨便找一個能夠運(yùn)行的程序的源代碼,比如下面的文件test.c:
?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void my_print (char *);
static void my_print2 (char *); main ()
{
char my_string[] = "hello world!";
my_print (my_string);
my_print2 (my_string);
my_print (my_string);
} void count_sum()
{
int i,sum=0;
for(i=0; i<1000000; i++)
sum += i;
}
void my_print (char *string)
{
count_sum();
printf ("The string is %s ", string);
} void my_print2 (char *string)
{
char *string2; int size, i,sum =0; count_sum();
size = strlen (string);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size -1 - i] = string[i]; string2[size] =' ';
for(i=0; i<5000000; i++)
sum += i;
printf ("The string printed backward is %s ", string2);
}
首先,用以下命令進(jìn)行編譯:
?????? [root@localhost]#gcc –o test –pg test.c
然后,運(yùn)行可執(zhí)行文件test.
?????? [root@localhost]#./test
運(yùn)行后,在當(dāng)前目錄下將生成一個文件gmon.out,這就是gprof生成的文件,保存有程序運(yùn)行期間函數(shù)調(diào)用等信息。
最后,用gprof命令查看gmon.out保存的信息:
?????? [root@localhost]#gprof test gmon.out –b
這樣就有一大堆信息輸出到屏幕上,有函數(shù)執(zhí)行單間,函數(shù)調(diào)用關(guān)系圖等等,如下:
?也可以使用命令$ gprof hello | more
以上介紹了gprof最簡單的使用方法,下面針對其使用過程中的三個步驟詳細(xì)說明。
編譯和鏈接
上面的例子中,程序比較簡單,只有一個文件。如果源代碼有多個文件,或者代碼結(jié)構(gòu)比較復(fù)雜,編譯過程中先生成若干個目標(biāo)文件,然后又由鏈接器將這些目標(biāo)文件鏈接到一起,這時該怎么使用gprof呢?
對于由多個源文件組成的程序,編譯時需要在生成每個.o文件的時候加上-pg參數(shù),同時在鏈接的時候也要加上-pg參數(shù)。對于鏈接器不是GCC的情況,如ld,又有特殊的要求。
同時,-pg參數(shù)只能記錄源代碼中各個函數(shù)的調(diào)用關(guān)系,而不能記錄庫函數(shù)的調(diào)用情況。要想記錄每個庫函數(shù)的調(diào)用情況,鏈接的時候必須指定庫函數(shù)的動態(tài)(或者靜態(tài))鏈接庫libc_p.a,即加上-lc_p,而不是-lc。
還要說明的是,如果有一部分代碼在編譯時指定了-pg參數(shù),而另一部分代碼沒有指定,則生成的gmon.out文件中將缺少一部分函數(shù),也沒有那些函數(shù)的調(diào)用關(guān)系。但是并不影響gprof對其它函數(shù)進(jìn)行記錄。
運(yùn)行
編譯好的程序運(yùn)行時和運(yùn)行一般的程序沒有什么不同,只是比正常的程序多生成了一個文件gmon.out。注意,這個文件名是固定的,沒法通過參數(shù)的設(shè)置進(jìn)行改變。如果程序目錄中已經(jīng)有一個gmon.out,則它會被新的gmon.out覆蓋掉。
關(guān)于生成的gmon.out文件所在的目錄,也有以下約定:程序退出時所運(yùn)行的文件所在目錄就是生成的gmon.out文件所在的目錄。如果一個程序執(zhí)行過程中調(diào)用了另一個程序,并在另一個程序的運(yùn)行中終止,則gmon.out會在另一個程序所在的目錄中生成。
還有一點(diǎn)要注意的就是當(dāng)程序非正常終止時不會生成gmon.out文件,也因此就沒法查看程序運(yùn)行時的信息。只有當(dāng)程序從main函數(shù)中正常退出,或者通過系統(tǒng)調(diào)用exit()函數(shù)而退出時,才會生成gmon.out文件。而通過底層調(diào)用如_exit()等退出時不會生成gmon.out。
查看
查看程序運(yùn)行信息的命令是gprof,它以gmon.out文件作為輸入,也就是將gmon.out文件翻譯成可讀的形式展現(xiàn)給用戶。其命令格式如下:
?????? gprof [可執(zhí)行文件] [gmon.out文件] [其它參數(shù)]
方括號中的內(nèi)容可以省略。如果省略了“可執(zhí)行文件”,gprof會在當(dāng)前目錄下搜索a.out文件作為可執(zhí)行文件,而如果省略了gmon.out文件,gprof也會在當(dāng)前目錄下尋找gmon.out。其它參數(shù)可以控制gprof輸出內(nèi)容的格式等信息。最常用的參數(shù)如下:
l???????? -b 不再輸出統(tǒng)計圖表中每個字段的詳細(xì)描述。
l???????? -p 只輸出函數(shù)的調(diào)用圖(Call graph的那部分信息)。
l???????? -q 只輸出函數(shù)的時間消耗列表。
l???????? -e Name 不再輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖(除非它們有未被限制的其它父函數(shù))。可以給定多個 -e 標(biāo)志。一個 -e 標(biāo)志只能指定一個函數(shù)。
l???????? -E Name 不再輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖,此標(biāo)志類似于 -e 標(biāo)志,但它在總時間和百分比時間的計算中排除了由函數(shù)Name 及其子函數(shù)所用的時間。
l???????? -f Name 輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖。可以指定多個 -f 標(biāo)志。一個 -f 標(biāo)志只能指定一個函數(shù)。
l???????? -F Name 輸出函數(shù)Name 及其子函數(shù)的調(diào)用圖,它類似于 -f 標(biāo)志,但它在總時間和百分比時間計算中僅使用所打印的例程的時間。可以指定多個 -F 標(biāo)志。一個 -F 標(biāo)志只能指定一個函數(shù)。-F 標(biāo)志覆蓋 -E 標(biāo)志。
l???????? -z 顯示使用次數(shù)為零的例程(按照調(diào)用計數(shù)和累積時間計算)。
不過,gprof不能顯示對象之間的繼承關(guān)系,這也是它的弱點(diǎn).
?
gprof 實現(xiàn)原理:
gprof并不神奇,在編譯和鏈接程序的時候(使用 -pg 編 譯和鏈接選項),gcc 在你應(yīng)用程序的每個函數(shù)中都加入了一個名為mcount(or“_mcount”, or“__mcount”) 的函數(shù),也就是說-pg編譯的應(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ù)等等的所有信息。
?
總結(jié)
以上是生活随笔為你收集整理的程序分析工具gprof介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux在多核处理器上的负载均衡原理
- 下一篇: 有规律格式化文本文件插入数据库