1、gcov
1.1 什么是gcov
首先我們要了解什么是gcov,gcov伴隨gcc 發布。gcc編譯加入-fprofile-arcs -ftest-coverage 參數生成二進制程序,執行測試用例生成代碼覆蓋率信息。
1.2 如何使用gcov
用GCC編譯的時候加上-fprofile-arcs -ftest-coverage選項,鏈接的時候也加上。
fprofile-arcs參數使gcc創建一個程序的流圖,之后找到適合圖的生成樹。只有不在生成樹中的弧被操縱(instrumented):gcc添加了代碼來清點這些弧執行的次數。當這段弧是一個塊的唯一出口或入口時,操縱工具代碼(instrumentation code)將會添加到塊中,否則創建一個基礎塊來包含操縱工具代碼。
gcov主要使用.gcno和.gcda兩個文件。
.gcno是由-ftest-coverage產生的,它包含了重建基本塊圖和相應的塊的源碼的行號的信息。
.gcda是由加了-fprofile-arcs編譯參數的編譯后的文件運行所產生的,它包含了弧跳變的次數和其他的概要信息(而gcda只能在程序運行完畢后才能產生的)。
1.3 gcov 覆蓋分類
Gcov執行函數覆蓋、語句覆蓋和分支覆蓋。
舉個例子,程序代碼由main.c和test.c兩個文件組成,編譯、鏈接、運行程序
編譯:gcc -fprofile-arcs -ftest-coverage -o myapp main.c test.c
運行:./myapp
然后 輸入
gcov main.c,gcov tmp.c
這個時候當前目錄下有了新的文檔main.c.gcov,和tmp.c.gcov
若想保存覆蓋率文件,上述命令修改為:
命令:gcov main.c >>yourfilename,gcov tmp.c >>yourfilename
而這時候的main.c.gcov,和tmp.c.gcov就包含了函數和代碼執行次數的信息,我們可以查看結果:
-: 0:Source:main.cpp
-: 0:Graph:main.gcno
-: 0:Data:main.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include <iostream>
-: 2:using namespace std;
1: 3:int main()
-: 4:{
-: 5: int i,total;
1: 6: total = 0;
-: 7:
11: 8: for (i=0; i<10; i++)
10: 9: total += i;
-: 10:
1: 11: if (total != 45)
#####: 12: cout << "Failure!" << endl;
-: 13: else
1: 14: cout << "Success!" << endl;
1: 15: return 0;
3: 16:}
##### 這就是表示沒跑到的
1.4 gcov參數
關於gcov的參數,可以在linux環境下使用gcov查閱
2、關於lcov
2.1 什么是lcov
Lcov則是上的gcov 結果展現的一個前端,可以將覆蓋率信息轉換成html展現。
2.2 生成覆蓋率
前提條件:使用 GCC 以 -fprofile-arcs 和-ftest-coverage 選項編譯程序。
a)假設編譯目錄名稱為 "/root/test/code_cover/",下面有個test.c,然后執行:
gcc -fprofile-arcs -ftest-coverage -o test test.c ./test
則會在/root/test/code_cover/目錄下生成test.gcno和test.gcda文件
注:一般情況,gcda和gcno會在同一個目錄,假如在編譯機器上面是test/path,編譯的時候會在這個目錄下生成*.gcno文件,那么在執行機器上也會生成*.gcda文件在test/path目錄下,
如果要使用lcov統計覆蓋率,必須將gcno和gcda放在同一個目錄,並且有源代碼,且源代碼的目錄和編譯時的目錄一樣,否則不能生成。
然后cd該目錄下執行
lcov --directory . --capture --output-file app.info
其中:
--directory 或者-d 表示的是目錄,也就是gcno和gcda目錄
--capture 或者 -c 表示獲取覆蓋率信息
--output-file 或者 -o 表示輸出文件
b) 獲取 HTML 輸出
genhtml -o results app.info
results是一個目錄,index.html為導航文件,使用 web 瀏覽器打開 index.html 文件查看代碼覆蓋結果。
2.3 lcov文件過濾
在某些情況下,比如三方庫不需要統計覆蓋率信息,則需要屏蔽,或者只需要某些文件的覆蓋率,就需要對文件進行篩選
a)移除指定目錄
lcov --remove all.info '/src/include/*' '/user/bin/*' -o result.info
此命令表示生成的覆蓋率信息,屏蔽 '/src/include/*' '/user/bin/*' 兩個目錄的覆蓋率信息
all.info 總的覆蓋率信息
result.info 篩選后的覆蓋率信息
b)只要固定目錄
lcov --extract all.info '*/src/*' '*/lib/*' -o result.info
此命令表示生成的覆蓋率信息只要src和lib目錄下文件的覆蓋率信息
all.info 總的覆蓋率信息
result.info 篩選后的覆蓋率信息
