Content
1. gcov是什麼?
2. gcov能做什麼?
3. 如何使用gcov?
3.1 使用gcov的3個階段
(1) 編譯
(2) 收集資訊
(3) 報告
3.2 gcov的選項
(1) -a, --all-blocks
(2) -b, --branch-probabilities
(3) -c, --branch-counts
4. 小結
1. gcov是什麼?
- Gcov is GCC Coverage
- 是一個測試代碼覆寫率的工具
- 是一個指令行方式的控制台程式
- 伴随GCC釋出,配合GCC共同實作對C/C++檔案的語句覆寫和分支覆寫測試;
- 與程式概要分析工具(profiling tool,例如gprof)一起工作,可以估計程式中哪一段代碼最耗時;
注:程式概要分析工具是分析代碼性能的工具。
2. gcov能做什麼?
gcov可以統計
- 每一行代碼的執行頻率
- 實際上哪些代碼确實被執行了
- 每一段代碼(section code)的耗時(執行時間)
是以,gcov可以幫你優化代碼,當然這個優化動作還是應該有開發者完成。
3. 如何使用gcov?
筆者也以gcov的manual頁自帶的例子為例,代碼(沒有做任何改動)如下。
filename: test.c
3.1 使用gcov的3個階段
(1) 編譯
# gcc -fprofile-arcs -ftest-coverage -o test test.c
# ls
test test.c test.gcno
-fprofile-arcs -ftest-coverage告訴編譯器生成gcov需要的額外資訊,并在目标檔案中插入gcov需要的extra profiling information。是以,該指令在生成可執行檔案test的同時生成test.gcno檔案(gcov note檔案)。
(2) 收集資訊
# ./test
Success
# ls
test test.c test.gcda test.gcno
執行該程式,生成test.gcda檔案(gcov data檔案)。
(3) 報告
# gcov test.c
File 'test.c'
Lines executed:87.50% of 8
test.c:creating 'test.c.gcov'
# ls
test test.c test.c.gcov test.gcda test.gcno
生成test.c.gcov檔案,該檔案記錄了每行代碼被執行的次數。
test.c.gcov檔案内容如下,藍色表示筆者添加的注釋。
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include //前面的數字表明該clause被執行的次數,下同
-: 2:
-: 3:int main (void)
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++) //前面的數字11表明該clause被執行11次
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
#####: 13: printf ("Failure/n");
-: 14: else
1: 15: printf ("Success/n");
1: 16: return 0;
-: 17:}
-: 18:
3.2 gcov的選項
gcov的選項不多,也好了解,此處選3個典型的選項并結合例子加以說明。
(1) -a, --all-blocks
在.gcov檔案中輸出每個基本快(basic block)的執行次數。如果沒有-a選項,則輸出'main'函數這個block的執行次數,如上所示。使用該選項可以
Write individual execution counts for every basic block. Normally gcov outputs execution counts only for the main blocks of a line. With this option you can determine if blocks within a single line are not being executed.
# gcov -a test.c
File 'test.c'
Lines executed:87.50% of 8
test.c:creating 'test.c.gcov'
Test.c.gcov檔案内容。
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:int main (void)
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++)
1: 9-block 0
10: 9-block 1
11: 9-block 2
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
1: 12-block 0
#####: 13: printf ("Failure/n");
$$$$$: 13-block 0
-: 14: else
1: 15: printf ("Success/n");
1: 15-block 0
1: 16: return 0;
1: 16-block 0
-: 17:}
-: 18:
(2) -b, --branch-probabilities
在.gcov檔案中輸出每個分支的執行頻率,并有分支統計資訊。
# gcov -b test.c
File 'test.c'
Lines executed:87.50% of 8
Branches executed:100.00% of 4
Taken at least once:75.00% of 4
Calls executed:50.00% of 2
test.c:creating 'test.c.gcov'
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:int main (void)
function main called 1 returned 100% blocks executed 86%
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++)
branch 0 taken 91%
branch 1 taken 9% (fallthrough)
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 13: printf ("Failure/n");
call 0 never executed
-: 14: else
1: 15: printf ("Success/n");
call 0 returned 100%
1: 16: return 0;
-: 17:}
-: 18:
(3) -c, --branch-counts
在.gcov檔案中輸出每個分支的執行次數。
# gcov -c test.c
File 'test.c'
Lines executed:87.50% of 8
test.c:creating 'test.c.gcov'
-c是預設選項,其結果與"gcov test.c"執行結果相同。
其他選項,請讀者參考相關文檔。
4. 小結
本文簡單介紹了Linux平台GCC自帶的代碼覆寫率測試工具GCOV的基本情況是使用方法。詳細研究需要參考官方文檔或者一些研究者的論文。