娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

GCC編譯器原理(一)03------GCC 工具:gprof、ld、libbfd、libiberty 和libopcodes

發布者:EternalSunset最新更新時間:2024-08-22 來源: cnblogs關鍵字:GCC編譯器  GCC  工具 手機看文章 掃描二維碼
隨時隨地手機看文章

1.3.7 gprof:性能分析工具

gprof是GNU profile工具,可以運行于linux、AIX、Sun等操作系統進行C、C++、Pascal、Fortran程序的性能分析,用于程序的性能優化以及程序瓶頸問題的查找和解決。通過分析應用程序運行時產生的 'flat profile',可以得到每個函數的調用次數,每個函數消耗的處理器時間,也可以得到函數的 '調用關系圖' ,包括函數調用的層次關系,每個函數調用花費了多少時間。

  • Gprof具有以下優缺點:

    • 需要編譯選項支持:

    • 調試多線程程序只能統計主線程的信息(所以不能用于 kingbase)。

    • 例如:gcc -pg -o test test.cpp ,編譯器會自動在目標代碼中插入用于性能測試的代碼片斷,這些代碼在程序運行時采集并記錄函數的調用關系和調用次數,并記錄函數自身執行時間和被調用函數的執行時間。

    • 執行編譯后的可執行程序,如:./test。該步驟運行程序的時間會稍慢于正常編譯的可執行程序的運行時間。程序運行結束后,會在程序所在路徑下生成一個缺省文件名為 gmon.out 的文件,這個文件就是記錄程序運行的性能、調用關系、調用次數等信息的數據文件。

    • 使用 gprof 命令來分析記錄程序運行信息的 gmon.out 文件,如:gprof test gmon.out 則可以在顯示器上看到函數調用相關的統計、分析信息。上述信息也可以采用 gprof test gmon.out > gprofresult.txt 重定向到文本文件以便于后續分析。

    • 使用 gcc/cc 或 g++ 編譯和鏈接時需要加入 -pg 選項;

    • 使用 ld 鏈接時需要用 /lib/gcrt0.o 代替 crt0.o 作為第一個 input 文件

    • 如果要調試 libc 庫需要使用 -lc_p代替 -lc 參數

    • GNU工具,人手一個;

    • 混合方法采集信息。

    • 優點:

    • 缺點:

命令行選項如下:

選項

描述

-b

不再輸出統計圖表中每個字段的詳細描述。

-q

只輸出函數的調用圖(Call graph的那部分信息)。

-p

只輸出函數的時間消耗列表。

-e Name

不再輸出函數 Name 及其子函數的調用圖(除非它們有未被限制的其它父函數)。可以給定多個 -e 標志。一個 -e 標志只能指定一個函數。

-E Name

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

-f Name

輸出函數 Name 及其子函數的調用圖。可以指定多個 -f 標志。一個 -f 標志只能指定一個函數。

-F Name

輸出函數 Name 及其子函數的調用圖,它類似于 -f 標志,但它在總時間和百分比時間計算中僅使用所打印的例程的時間。可以指定多個 -F 標志。一個 -F 標志只能指定一個函數。-F 標志覆蓋 -E 標志。

-z

顯示使用次數為零的例程(按照調用計數和累積時間計算)。

例子:

 1 #include

 2 #include

 3 int a(void)

 4 {

 5     int i=0,g=0;

 6     while(i++ < 100000)

 7     {

 8         g+=i;

 9     }

10     

11     return g;

12 }

13 

14 int b(void)

15 {

16     int i=0,g=0;

17     

18     while(i++ < 400000)

19     {

20         g +=i;

21     }

22     

23     return g;

24 }

25 

26 int main(int argc, char** argv)

27 {

28     int iterations;

29     

30     if(argc != 2)

31     {

32         printf('Usage %s n', argv[0]);

33         exit(-1);

34     }

35     else

36         iterations = atoi(argv[1]);

37     printf('No of iterations = %dn', iterations);

38     

39     while(iterations--)

40     {

41         a();

42         b();

43     }

44 }

 

應用程序包括兩個函數:a 和 b,它們通過運行不同次數的循環來消耗不同的CPU時間。

main 函數中采用了一個循環來反復調用這兩個函數。函數 b 中循環的次數是 a 函數的 4 倍,因此我們期望通過 gprof 的分析結果可以觀察到大概有 20% 的時間花在了 a 函數中,而 80% 的時間花在了 b 函數中。

編譯程序:gcc test.c -pg -o test -O2 -lc

運行并傳入參數:./test 50000

程序運行完之后,會在目錄下生成一個 gmon.out 文件:

使用 gprof 命令分析分析 gmon.out 文件gprof test gmon.out -p

程序運行時間太短,所以 gprof 無效,若是大程序即可使用此來分析。

上面那些參數得含義如下:

名稱

含義

%time

函數以及衍生函數(函數內部再次調用的子函數)所占的總運行時間的百分比

cumulative seconds

函數累計執行的時間

self seconds

函數執行占用的時間

calls

函數的調用次數

self ms/call

每一次調用函數花費的時間microseconds,不包括衍生函數的運行時間

total ms/call

每一次調用函數花費的時間microseconds,包括衍生函數的運行時間

name

函數名稱

 

1.3.8 ld:GNU 鏈接器

ld 是 GNU 工具鏈中的一個軟件,主要用于將 obj 文件鏈接成可執行文件。同時可以使用自己的腳本來控制 ld 的行為,可以通過 -T 選項選擇自己的腳本而不是默認的。

選項

描述

-static

靜態鏈接

-l

指定鏈接某個庫

-e name

指定 name 為程序入口

-r

合并目標文件,不進行最終鏈接

-L

指定鏈接時查找路徑,多個路徑之間用冒號隔開

-M

將鏈接時的符號和地址輸出成一個映射文件

-o

指定輸出的文件名

-s

清除輸出文件中的符號信息

-shared

鏈接器生成一個 Linux 上使用的動態庫

-S

清除輸出文件中的調試信息

-T

指定鏈接腳本文件

-Ttext

指定 text 段的地址

-version-script

指定符號版本腳本文件

-soname

指定輸出動態庫的 SONAME

-export-dynamic

將全局符號全部導出

-verbose

鏈接時輸出詳細信息

-rpath

指定鏈接時庫查找路徑

--help

查看鏈接器的幫助信息

1.3.9 libbfd:二進制文件描述器

libbfd 工具不會在安裝 binutils 的時候自動安裝,需要在 binutils 安裝包的 bfd 文件夾下單獨安裝。

在安裝完 binutils 工具之后就可以看到此工具。安裝完成后,會生成如下文件:

  • /usr/local/include/bfd.h

  • /usr/local/lib/libbfd.a

可以利用此工具獲取 elf 可執行文件的 section(節) 及 symbol(符號) 信息。

使用此工具需要注意的地方:

  1. 頭文件包含

    1. 采用GNU autotools的項目,在編譯前一般都會執行一下 configure 腳本,生成 Makefile 及 config.h文 件。

    2. 對于沒有使用 GNU autotools 的應用,可以采用如下格式得到 config.h 文件,這個文件的內容,相當于是使用 GNU autotools 開發一個 hello world 項目而得到的 config.h,下面就是 config.h 文件的模板

    3. 程序使用bfd,需要包含bfd.h頭文件。但是,在包含 bfd.h 之前,還需要包含 config.h。即代碼中需要有如下形式的文件包含:

    4.     #include 'config.h'
          #include 

    5. config.h 不是系統的頭文件,也不是bfd庫的頭文件,而是應用程序自己的頭文件。

 

 1 /* config.h.  Generated from config.h.in by configure.  */

 2 /* config.h.in.  Generated from configure.ac by autoheader.  */

 3      

 4 /* Name of package */

 5 #define PACKAGE 'hello'

 6      

 7 /* Define to the address where bug reports for this package should be sent. */

 8 #define PACKAGE_BUGREPORT 'bug-report@address'

 9      

10 /* Define to the full name of this package. */

11 #define PACKAGE_NAME 'hello'

12      

13 /* Define to the full name and version of this package. */

14 #define PACKAGE_STRING 'hello 1.0'

15      

16 /* Define to the one symbol short name of this package. */

17 #define PACKAGE_TARNAME 'hello'

18      

19 /* Define to the home page for this package. */

20 #define PACKAGE_URL ''

21      

22 /* Define to the version of this package. */

23 #define PACKAGE_VERSION '1.0'

24      

25 /* Version number of package */

26 #define VERSION '1.0'


  1. 鏈接

    1. 鏈接的時候需要帶上這幾個庫:bfd iberty dl z

    2. 例如,假設 hello.c 是一個完整的使用 bfd 庫的程序,則他的編譯方法如:gcc hello.c -lbfd -liberty -ldl -lz

例子如下:

 1 #include

 2 #include

 3 #include 'config.h'

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9  

10 /* 

11    這里定義 3 個 static 變量,并把他們放到一個單獨的 section 中。

12    后面,我們通過 bfd 找出這個 section,并得到這 3 個變量的內容。

13    同時,我們還通過符號查找操作,找到 a_haha 這個 static 變量的信息。

14 */

15 static uint64_t  a_haha   __attribute__((section ('my_test_sec'))) =3;

16 static uint64_t  b        __attribute__((section ('my_test_sec'))) =7;

17 static uint64_t  c        __attribute__((section ('my_test_sec'))) =8;

18  

19 /* 獲取當前進程自己的elf文件路徑 */

20 int get_self_path(char *buf, int buf_len)

21 {

22     int ret = readlink('/proc/self/exe', buf, buf_len);

23     buf[ret]='

主站蜘蛛池模板: 浙江省| 龙胜| 宁夏| 侯马市| 临沂市| 延庆县| 朔州市| 绥宁县| 将乐县| 余江县| 中卫市| 和林格尔县| 七台河市| 韶关市| 紫阳县| 万载县| 博白县| 馆陶县| 沅江市| 囊谦县| 柯坪县| 景谷| 鞍山市| 肥东县| 合肥市| 崇明县| 烟台市| 钟山县| 济南市| 临泉县| 鄂托克旗| 蛟河市| 华池县| 山丹县| 民乐县| 安化县| 浦江县| 陈巴尔虎旗| 诸暨市| 邯郸市| 湘阴县|