开启gcov
看下当前config里面是不是已经enable了gcov:
1 | $ zcat /proc/config.gz | egrep "GCOV_|DEBUG_FS" |
通常答案都是否定的,默认情况下一般不会开启。那就修改一下.config
文件,重新编译、安装kernel。 过程略。
正确开启gcov之后,除了上面几个几部之外,可以通过下面kernel Document来验证:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17The gcov kernel support creates the following files in debugfs:
/sys/kernel/debug/gcov
Parent directory for all gcov-related files.
/sys/kernel/debug/gcov/reset
Global reset file: resets all coverage data to zero when
written to.
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda
The actual gcov data file as understood by the gcov
tool. Resets file coverage data to zero when written to.
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno
Symbolic link to a static data file required by the gcov
tool. This file is generated by gcc when compiling with
option -ftest-coverage.
收集code coverage信息
code coverage的信息收集需要2+1步:
- 收集
*.gcda
- 在编译kernel的环境中,转换为 .info
- 生成HTML文档
收集 *.gcda
gcov 官网非常贴心的给提供了一个脚本:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#!/bin/bash -e
DEST=$1
GCDA=/sys/kernel/debug/gcov/home/works/linux-stable/
if [ -z "$DEST" ] ; then
echo "Usage: $0 <output.tar.gz>" >&2
exit 1
fi
TEMPDIR=$(mktemp -d)
echo Collecting data..
find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
# find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
tar czf $DEST -C $TEMPDIR/$GCDA .
rm -rf $TEMPDIR
echo "$DEST successfully created, copy to build system and unpack with:"
echo " tar xfz $DEST"
这个脚本打包的那句感觉写的不是很准确,我稍微修改了一下。
注意,这个脚本必须在/sys/kernel/debug/gcov/home/works/linux-stable/
这个目录下运行\
并且,中间那个手机*.gcno
文件的一句话也不需要,而且是绝对不能加的。
脚本会把所有当前kernel内所有的文件的.gcda
打包到参数$1
指定的文件中,并且,最后告诉了解压的方法。
把.gcda放回编译环境
打包的.gcda
如何使用呢? scp 到kernel编译环境,然后在内核根目录linux
下执行上面的解压缩程序:1
tar xfz <文件名>
成功之后,所有的.gcda
文件就解压到对应的.c
以及.c.gcno
文件旁边。
转换
使用lcov
工具,把gcov log文件转换位.info。同样,lcov官网也给出了建议的流程:1
2
3
4
5
6
7
8
9
10
11
12
13
14Recommended procedure when capturing data for a test case:
1. create baseline coverage data file
# lcov -c -i -d appdir -o app_base.info
2. perform test
# appdir/test
3. create test coverage data file
# lcov -c -d appdir -o app_test.info
4. combine baseline and test coverage data
# lcov -a app_base.info -a app_test.info -o app_total.info
如果build环境和测试环境分开的话,也不需要严格的按照上面的步骤来。但上面的步骤至少提供了两个信息:
- lcov怎么用
- 如何合并多个info文件
同样在内核根目录下,执行1
2# lcov -c -i -d . -o app_base.info
然后去执行测试,并且重复上面.gcda
文件的打包和解包过程,之后再执行:1
2# lcov -c -d appdir -o app_test.info
# lcov -a app_base.info -a app_test.info -o app_total.info
生成网页报告
使用工具genhtml
,把最终的app_tatal.info
文件转为html文件:1
genhtml test.info --output-directory output --title "a simple test" --show-details --legend
gcov在user space下使用
添加
-ftest-coverage -fprofile-arcs
变选项1
gcc -ftest-coverage -fprofile-arcs main.c -o main
使用gcov抓取coverage
1
gcov main.c
使用lcov 和 genhtml生成报告
1 | lcov -c -o main.info -d . |
gcov for kernel modles
同样需要先enable kernel config
用hello.c
和 makefile
举例:
- 修改Makefile
添加如下:1
2
3GCOV_PROFILE := y
CFLAGS=-ftest-coverage -fprofile-arcs
export CFLAGS - 编译模块
1
make
插入模块
1
insmod hello.ko
gcda文件
1
/sys/kernel/debug/gcov/<your dir>/program.gcda
cat并保存.gcda和.gcno到project目录
gcov
1
gcov hello.c
生成html
1
2lcov -c -o hello.info -d .
genhtml hello.info -o main_result删除gcov文件
删除include
开头的文件或者文件夹1
# lcov -r hell.info "include*" -o hello.info2