Linux进程核心代码怎么查看,GCOV查看arm-linux代码覆盖率
一、關于gcov工具
gcov伴隨gcc發布。gcc編譯加入-fprofile-arcs -ftest-coverage參數生成二進制程序,執行測試用例生成代碼覆蓋率信息。1、如何使用gcov
用GCC編譯的時候加上-fprofile-arcs -ftest-coverage選項,鏈接的時候也加上。fprofile-arcs參數使gcc創建一個程序的流圖,之后找到適合圖的生成樹。只有不在生成樹中的弧被操縱(instrumented):gcc添加了代碼來清點這些弧執行的次數。當這段弧是一個塊的唯一出口或入口時,操縱工具代碼(instrumentation code)將會添加到塊中,否則創建一個基礎塊來包含操縱工具代碼。
gcov主要使用.gcno和.gcda兩個文件。.gcno是由-ftest-coverage產生的,它包含了重建基本塊圖和相應的塊的源碼的行號的信息。.gcda是由加了-fprofile-arcs編譯參數的編譯后的文件運行所產生的,它包含了弧跳變的次數和其他的概要信息(而gcda只能在程序運行完畢后才能產生的)。Gcov執行函數覆蓋、語句覆蓋和分支覆蓋。
舉個例子,程序代碼由main.c和tmp.c兩個文件組成,編譯、鏈接、運行程序編譯:gcc -fprofile-arcs -ftest-coverage -o myapp main.c tmp.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就包含了函數和代碼執行次數的信息,我們可以查看結果:-: ??65:/***************************************************************************************
-: ??66: * name ????????: main
-: ??67: * return ??????: 0 OK
-: ??68: * ???????????????other ERROR
-: ??69: * history ?????: 2006-06-13
-: ??70:****************************************************************************************/
-: ??71:int main( int argc, char *argv[] ) ?????????????????????????????????????????????????????/* the entrance for program
*/
function main called 4 returned 100% blocks executed 81%
4: ??72:{
4: ??73: ???????int loop = 0 ;
4: ??74: ???????int ret = OK ;
4: ??75: ???????int empty_line = 0 ;
4: ??76: ???????int code_line = 0 ;
4: ??77: ???????int annotation_line = 0 ;
4: ??78: ???????struct stat file_stat ; ????????????????????????????????????????????????????????/* use for file state */
4: ??79: ???????char recu_name[256] ;
4: ??80: ???????char *pwd = NULL ;
4: ??81: ???????char *tmp = NULL ;
-: ??82:
4: ??83: ???????if( argc = MAX_FILE ){ ???????????????????????????????????/* file size larger than max size */
#####: ??98: ???????????????????????printf( "file [%s] size is over 64K! \ncontinue....\n", argv[loop] ) ;
#####: ??99: ???????????????????????continue ;
-: 100: ???????????????}
#####這就是表示沒跑到的
各個參數使用如下:gcov [-b] [-c] [-v] [-n] [-l] [-f] [-o directory] sourcefile
-b
Write branch frequencies to the output file, and write branch summary info to the standard output. This option allows you to
see how often each branch in your program was taken.
//b(ranch),分支測試-c
Write branch frequencies as the number of branches taken, rather than the percentage of branches taken.
-v
Display the gcov version number (on the standard error stream).
//太簡單了吧,我上面用了-n
Do not create the gcov output file.
-l
Create long file names for included source files. For example, if the header file `x.h' contains code, and was included in the
file `a.c', then running gcov on the file `a.c' will produce an output file called `a.c.x.h.gcov' instead of `x.h.gcov'. This can
be useful if `x.h' is included in multiple source files.
-f
Output summaries for each function in addition to the file level summary.
-o
The directory where the object files live. Gcov will search for `.bb', `.bbg', and `.da' files in this directory.新版的是這么說的-o directory│file
--object-directory directory
--object-file file
Specify either the directory containing the gcov data files, or the
object path name. The .gcno, and .gcda data files are searched for
using this option. If a directory is specified, the data files are
in that directory and named after the source file name, without its
extension. If a file is specified here, the data files are named
after that file, without its extension. If this option is not sup-
plied, it defaults to the current directory.其他的更有新版的-u,
-u
--unconditional-branches
When branch counts are given, include those of unconditional
branches. Unconditional branches are normally not interesting.
-p
--preserve-paths
Preserve complete path information in the names of generated .gcov
files. Without this option, just the filename component is used.
With this option, all directories are used, with ’/’ characters
translated to ’#’ characters, ’.’ directory components removed and
’..’ components renamed to ’^’. This is useful if sourcefiles are
in several different directories. It also affects the -l option.
二、關于lcov
Lcov則是上的gcov結果展現的一個前端,可以將覆蓋率信息轉換成html展現。
1.如何訪問用戶空間應用程序代碼覆蓋數據的示例---------------------------------------------------------------------前提條件:使用GCC以-fprofile-arcs和-ftest-coverage選項編譯程序。假設編譯目錄名稱為"/root/test/code_cover/",然后執行:
以我的一個實例/root/test/code_cover/下的fork.c為例看代碼的覆蓋率:
首先進入/root/test/code_cover/目錄a)重置計數器lcov --directory . --zerocounters
b)收集當前代碼覆蓋狀態到一個文件(應用程序啟動和停止至少一次后,該命令才能正常工作)lcov --directory . --capture --output-file app.info
Capturing coverage data from .
Found gcov version: 3.4.6
Scanning . for .gcda files ...
Found 1 data files in .
Processing ./TestQuery.gcda
Finished .info-file creation
c)獲取HTML輸出genhtml -o results app.info
其中的“-o results”是指示結果存放在什么位置的。
Readingdata file app.info
Found 18 entries.
Found common filename prefix "/home/search/isearch_yb/src"
Writing .css and .png files.
Generating output.
Processing file cpp/core/basis/GlobalDef.h
Processing file cpp/core/search/QueryCache.h
...
Writing directory view page.
Overall coverage rate: 117 of 514 lines (22.8%)使用web瀏覽器打開index.html文件查看代碼覆蓋結果。
三、Linux內核覆蓋率測試:
將最終的gcov內核模塊文件復制到system wide modules目錄或者PERL腳本所在目錄。以root身份,執行:
Gcov:在對Linux內核程序進行代碼覆蓋率測試時,同樣可以采用gcov,但是需要對kernel打一個補丁。Gcov的內核補丁下載地址:。下載gcov內核補丁(wget),解壓補丁,然后為一個kernel打補丁(patch –p1 < /home/linux-v3.4-mem/gcov-kernel-2/linux-2.6.18-gcov.patch)注意打補丁時應該處于內核的主目錄下也即/home/linux-v3.4-mem,打完補丁之后,通過make menuconfig配置gcov,配置頁面顯示如下:
配置完畢之后,重新編譯內核,將編譯成功的gcov這個內核模塊/home/linux-v3.4-mem /kernel/gcov/gcov-proc.ko拷貝到網絡文件系統下面,arm linux系統啟動后加載這個模塊
(1)/insmod gcov-proc.ko
然后再跑其他測試程序,跑了一段時間,你會發現在/proc/gcov目錄下有各種gcov的統計文件:
/proc/gcov # ls
arch ?????crypto ???init ?????kernel ???security ?vmlinux
block ????drivers ??ipc ??????net ??????sound
把這整個目錄拷貝到fedora虛擬機下的一個目錄,我是拷貝到/nfs/kernel_test/gcov目錄下,然后
(2)收集當前代碼覆蓋狀態到一個文件lcov --directory . --output-file kernel.info
(3)獲取HTML輸出genhtml kernel.info使用web瀏覽器打開index.html文件查看代碼覆蓋結果。
上面是怎樣獲取內核運行代碼覆蓋率的一般方法及流程。
但如果我們只想獲取一個程序運行時的內核代碼覆蓋率,改怎么辦呢???
這里先說幾個gcov-proc模塊的特性:
(1)模塊屬性:
我們發現/sys/module/gcov_proc下有parameters文件夾,進去我們發現有兩個屬性文件:
/sys/module/gcov_proc/parameters # ls
gcov_linkgcov_persist
這兩個屬性是控制什么的呢???看看官方表述:
- gcov_link=0/1 (default is 1): When set to non-zero, symbolic links to
source and gcov graph files are created in /proc/gcov along with the data
files.
- gcov_persist=0/1 (default is 0): When set to non-zero, gcov data for
kernel modules is kept even after those modules are unloaded so that
coverage measurements can be extended to module cleanup code. To clear
this persistent data, write to /proc/vmlinux.
(2)重啟內核覆蓋率采集的數據
To reset coverage data for a specific file, simply write to the associated data
file in the /proc/gcov hierarchy:
echo 0 > /proc/gcov/kernel/signal.da
To reset all coverage data, write to the extra file '/proc/gcov/vmlinux':
echo 0 > /proc/gcov/vmlinux
四、獲取程序運行時段的內核覆蓋率
我的方法是在運行應用程序(這里面是以我的/nfs/memtest/timetest下的timetest應用程序為例)的開始先用“echo 0 > /proc/gcov/vmlinux”指令將我們的/proc/gcov下的統計信息全部清空讓它重新計數的,下面說下我們的方法和步驟:
1、先獲得一個含義gcov信息的內核和gcov-proc.ko,這個上面已經說過了;
2、啟動linux內核,然后安裝gcov-proc.ko
/memtest # insmod gcov-proc.ko
gcov-proc: initializing proc module: persist=0 link=1 format=gcc 3.4
gcov-proc: init done
/memtest # cd timetest/
/memtest/timetest # ls
20100106.logfp2timetesttimetest.ctimetest.gcno
20100111.logresultstimetest-lcovtimetest.gcda
3、這時先用“echo 0 > /proc/gcov/vmlinux”指令清空gcov,然后運行timetest,然后將
/proc/gcov拷貝到/tmp下面,這是防止直接拷到虛擬機下會產生大量的網絡函數調用,增加統計誤差。
/memtest/timetest # echo 0 > /proc/gcov/vmlinux && ./timetest && cp -r /proc/gcov/ /tmp
game over count1 is 0xc9413e40,count2 is 0x0,count3 is 0x3c8b1e45,count4 is 0x0
/memtest/timetest # ls /tmp
gcov
4、現在統計的數據是放在/tp/gcov下面的,我們需要將之拷貝到上位機的虛擬機中才能分析,因為我們的lcov只能在虛擬機中才能運行的。
/memtest/timetest # cp -r /tmp/gcov/ ./
/memtest/timetest #
5、現在需要轉到虛擬機下接著運行lcov來產生最后的html頁面了。
[root@localhost timetest]# cd gcov/
[root@localhost gcov]# lcov --directory . --capture --output-file timetest.info
[root@localhost gcov]# genhtml -o results timetest.info
這樣就生成了最后基本上只運行在timetest時間段的內核代碼覆蓋率了。
總結
以上是生活随笔為你收集整理的Linux进程核心代码怎么查看,GCOV查看arm-linux代码覆盖率的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: const对象
- 下一篇: Mac下使用macdeployqt打包q