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的基本情況是使用方法。詳細研究需要參考官方文檔或者一些研究者的論文。
Reference
Gcov的manual頁
http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
http://dev.firnow.com/course/6_system/linux/Linuxjs/20071129/88999.html