why

QA要求对接gcov,不得已研究了一下


gcov是gcc自带的,需要两个编译选项和一个链接选项,

如果代码是makefile组织的,很简单

指定编译flag加上-fprofile-arcs -ftest-coverage,链接flag加上lgcov

比如rocksdb的写法

coverage:
	$(MAKE) clean
	COVERAGEFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS+="-lgcov" $(MAKE) J=1 all check
	cd coverage && ./coverage_test.sh
        # Delete intermediate files
	$(FIND) . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \;

如果是cmake组织的也很好办,cmake配置见参考链接1,写的很周全

我的项目也是cmake组织的,简化了一下

if(USE_GCOV)
	message(STATUS "using gcov")
	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage" )
#   SET(GCC_COVERAGE_LINK_FLAGS "-lgcov")
#   SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )               
    target_link_libraries(binary-namexxx gcov) 
endif(USE_GCOV)

其中两行set和下面的target_link_libraries是一个意思,set写法需要把所有的link管理都放在CMAKE_EXE_LINKER_FLAGS里。我的项目都是用target_link_libraries处理的,就放弃了这种写法

cmake生成makefile指定一下USE_GCOV就可以了,比如cmake -DUSE_GCOV=1

编译成功之后需要使用lcov进行分析,有两类文件.gcda .gcno需要分析

其中gcno是编译就会生成的,gcda是运行才会生成的。所以需要执行以下编译好的二进制文件

如果程序不会自动退出,需要graceful杀掉

ps -ef| pgrep binary-namexxx |while read -r num
do 
    kill -15 "$num"
done

或者

pkill binary-namexxx

注意,杀掉后可能停的比较慢,gcda文件handle还在写有可能破坏,手动延时一下

注意,两个文件所在的目录,一般来说,在二进制目录下,如果是cmake,在build/CMakeFile/binary-namexxx.dir/ 下,可以去目录下确定是否生成了文件

lcov安装可以yum或者git clone make install,github有教程

lcov依赖PerlIO::gzip和JSON,如果有报错,可以cpan安装或者手动下载,没报错跳过

cpan PerlIO::gzip
cpan JSON
# or
cd xxx
perl Makefile.PL 
make install

安装好后

执行

lcov -d . -c -o report.info

如果没有明显的报错提示,就是成功,然后生成report即可

genhtml report.info -o result
Reading data file test.info
Found 28 entries.
Found common filename prefix "/usr/local/include/c++"
Writing .css and .png files.
...
Processing file 5.4.0/ext/aligned_buffer.h
Writing directory view page.
Overall coverage rate:
  lines......: 84.5% (410 of 485 lines)
  functions..: 84.8% (28 of 33 functions)

就结束了,可以点开html观看

另外,参考链接中有gcov原理,可以学习一下

ref

  1. https://codeist.zone/2018/03/16/code-coverage-with-gcov-and-cmake/
  2. rocksdb coverage
    1. https://github.com/facebook/rocksdb/blob/5dc9fbd1175ad10454b877d9044c4b909d00ae3b/Makefile
    2. https://github.com/facebook/rocksdb/blob/master/coverage/coverage_test.sh
  3. lcov https://github.com/linux-test-project/lcov
  4. gcov 原理 http://rdc.hundsun.com/portal/article/704.html

contact