Linux进程核心代码怎么查看,GCOV查看arm-linux代码覆盖率
一、關(guān)于gcov工具
gcov伴隨gcc發(fā)布。gcc編譯加入-fprofile-arcs -ftest-coverage參數(shù)生成二進(jìn)制程序,執(zhí)行測(cè)試用例生成代碼覆蓋率信息。1、如何使用gcov
用GCC編譯的時(shí)候加上-fprofile-arcs -ftest-coverage選項(xiàng),鏈接的時(shí)候也加上。fprofile-arcs參數(shù)使gcc創(chuàng)建一個(gè)程序的流圖,之后找到適合圖的生成樹。只有不在生成樹中的弧被操縱(instrumented):gcc添加了代碼來清點(diǎn)這些弧執(zhí)行的次數(shù)。當(dāng)這段弧是一個(gè)塊的唯一出口或入口時(shí),操縱工具代碼(instrumentation code)將會(huì)添加到塊中,否則創(chuàng)建一個(gè)基礎(chǔ)塊來包含操縱工具代碼。
gcov主要使用.gcno和.gcda兩個(gè)文件。.gcno是由-ftest-coverage產(chǎn)生的,它包含了重建基本塊圖和相應(yīng)的塊的源碼的行號(hào)的信息。.gcda是由加了-fprofile-arcs編譯參數(shù)的編譯后的文件運(yùn)行所產(chǎn)生的,它包含了弧跳變的次數(shù)和其他的概要信息(而gcda只能在程序運(yùn)行完畢后才能產(chǎn)生的)。Gcov執(zhí)行函數(shù)覆蓋、語(yǔ)句覆蓋和分支覆蓋。
舉個(gè)例子,程序代碼由main.c和tmp.c兩個(gè)文件組成,編譯、鏈接、運(yùn)行程序編譯:gcc -fprofile-arcs -ftest-coverage -o myapp main.c tmp.c運(yùn)行:./myapp然后輸入命令:gcov main.c,gcov tmp.c
這個(gè)時(shí)候當(dāng)前目錄下有了新的文檔main.c.gcov,和tmp.c.gcov若想保存覆蓋率文件,上述命令修改為:命令:gcov main.c >>yourfilename,gcov tmp.c >>yourfilename
而這時(shí)候的main.c.gcov,和tmp.c.gcov就包含了函數(shù)和代碼執(zhí)行次數(shù)的信息,我們可以查看結(jié)果:-: ??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: ???????????????}
#####這就是表示沒跑到的
各個(gè)參數(shù)使用如下: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è)試-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).
//太簡(jiǎn)單了吧,我上面用了-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.
二、關(guān)于lcov
Lcov則是上的gcov結(jié)果展現(xiàn)的一個(gè)前端,可以將覆蓋率信息轉(zhuǎn)換成html展現(xiàn)。
1.如何訪問用戶空間應(yīng)用程序代碼覆蓋數(shù)據(jù)的示例---------------------------------------------------------------------前提條件:使用GCC以-fprofile-arcs和-ftest-coverage選項(xiàng)編譯程序。假設(shè)編譯目錄名稱為"/root/test/code_cover/",然后執(zhí)行:
以我的一個(gè)實(shí)例/root/test/code_cover/下的fork.c為例看代碼的覆蓋率:
首先進(jìn)入/root/test/code_cover/目錄a)重置計(jì)數(shù)器lcov --directory . --zerocounters
b)收集當(dāng)前代碼覆蓋狀態(tài)到一個(gè)文件(應(yīng)用程序啟動(dòng)和停止至少一次后,該命令才能正常工作)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”是指示結(jié)果存放在什么位置的。
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文件查看代碼覆蓋結(jié)果。
三、Linux內(nèi)核覆蓋率測(cè)試:
將最終的gcov內(nèi)核模塊文件復(fù)制到system wide modules目錄或者PERL腳本所在目錄。以root身份,執(zhí)行:
Gcov:在對(duì)Linux內(nèi)核程序進(jìn)行代碼覆蓋率測(cè)試時(shí),同樣可以采用gcov,但是需要對(duì)kernel打一個(gè)補(bǔ)丁。Gcov的內(nèi)核補(bǔ)丁下載地址:。下載gcov內(nèi)核補(bǔ)丁(wget),解壓補(bǔ)丁,然后為一個(gè)kernel打補(bǔ)丁(patch –p1 < /home/linux-v3.4-mem/gcov-kernel-2/linux-2.6.18-gcov.patch)注意打補(bǔ)丁時(shí)應(yīng)該處于內(nèi)核的主目錄下也即/home/linux-v3.4-mem,打完補(bǔ)丁之后,通過make menuconfig配置gcov,配置頁(yè)面顯示如下:
配置完畢之后,重新編譯內(nèi)核,將編譯成功的gcov這個(gè)內(nèi)核模塊/home/linux-v3.4-mem /kernel/gcov/gcov-proc.ko拷貝到網(wǎng)絡(luò)文件系統(tǒng)下面,arm linux系統(tǒng)啟動(dòng)后加載這個(gè)模塊
(1)/insmod gcov-proc.ko
然后再跑其他測(cè)試程序,跑了一段時(shí)間,你會(huì)發(fā)現(xiàn)在/proc/gcov目錄下有各種gcov的統(tǒng)計(jì)文件:
/proc/gcov # ls
arch ?????crypto ???init ?????kernel ???security ?vmlinux
block ????drivers ??ipc ??????net ??????sound
把這整個(gè)目錄拷貝到fedora虛擬機(jī)下的一個(gè)目錄,我是拷貝到/nfs/kernel_test/gcov目錄下,然后
(2)收集當(dāng)前代碼覆蓋狀態(tài)到一個(gè)文件lcov --directory . --output-file kernel.info
(3)獲取HTML輸出genhtml kernel.info使用web瀏覽器打開index.html文件查看代碼覆蓋結(jié)果。
上面是怎樣獲取內(nèi)核運(yùn)行代碼覆蓋率的一般方法及流程。
但如果我們只想獲取一個(gè)程序運(yùn)行時(shí)的內(nèi)核代碼覆蓋率,改怎么辦呢???
這里先說幾個(gè)gcov-proc模塊的特性:
(1)模塊屬性:
我們發(fā)現(xiàn)/sys/module/gcov_proc下有parameters文件夾,進(jìn)去我們發(fā)現(xiàn)有兩個(gè)屬性文件:
/sys/module/gcov_proc/parameters # ls
gcov_linkgcov_persist
這兩個(gè)屬性是控制什么的呢???看看官方表述:
- 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)重啟內(nèi)核覆蓋率采集的數(shù)據(jù)
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
四、獲取程序運(yùn)行時(shí)段的內(nèi)核覆蓋率
我的方法是在運(yùn)行應(yīng)用程序(這里面是以我的/nfs/memtest/timetest下的timetest應(yīng)用程序?yàn)槔?的開始先用“echo 0 > /proc/gcov/vmlinux”指令將我們的/proc/gcov下的統(tǒng)計(jì)信息全部清空讓它重新計(jì)數(shù)的,下面說下我們的方法和步驟:
1、先獲得一個(gè)含義gcov信息的內(nèi)核和gcov-proc.ko,這個(gè)上面已經(jīng)說過了;
2、啟動(dòng)linux內(nèi)核,然后安裝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、這時(shí)先用“echo 0 > /proc/gcov/vmlinux”指令清空gcov,然后運(yùn)行timetest,然后將
/proc/gcov拷貝到/tmp下面,這是防止直接拷到虛擬機(jī)下會(huì)產(chǎn)生大量的網(wǎng)絡(luò)函數(shù)調(diào)用,增加統(tǒng)計(jì)誤差。
/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、現(xiàn)在統(tǒng)計(jì)的數(shù)據(jù)是放在/tp/gcov下面的,我們需要將之拷貝到上位機(jī)的虛擬機(jī)中才能分析,因?yàn)槲覀兊膌cov只能在虛擬機(jī)中才能運(yùn)行的。
/memtest/timetest # cp -r /tmp/gcov/ ./
/memtest/timetest #
5、現(xiàn)在需要轉(zhuǎn)到虛擬機(jī)下接著運(yùn)行l(wèi)cov來產(chǎn)生最后的html頁(yè)面了。
[root@localhost timetest]# cd gcov/
[root@localhost gcov]# lcov --directory . --capture --output-file timetest.info
[root@localhost gcov]# genhtml -o results timetest.info
這樣就生成了最后基本上只運(yùn)行在timetest時(shí)間段的內(nèi)核代碼覆蓋率了。
總結(jié)
以上是生活随笔為你收集整理的Linux进程核心代码怎么查看,GCOV查看arm-linux代码覆盖率的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: const对象
- 下一篇: 网络存储 linux 访问,Linux基