LibFuzzer使用的覆盖率统计工具为Source-based Code Coverage。
另外两个clang实现的覆盖率统计实现:
- SanitizerCoverage: 低开销的工具。可以提供边级别的覆盖率统计;
- gcov: gcc兼容的覆盖率统计实现,基于DebugInfo。
-ftest-coverage
和--coverage
workflow
- 编译附带覆盖率信息
- 运行插桩程序
- 创建覆盖率报告
后面以下面的代码为例:ShowLineNumbers1 2 3 4 5 6 7 8 9 10 11
| % cat <<EOF > foo.cc #define BAR(x) ((x) || (x)) template <typename T> void foo(T x) { for (unsigned I = 0; I < 10; ++I) { BAR(I); } } int main() { foo<int>(0); foo<float>(0); return 0; } EOF
|
添加覆盖率配置
加入-fprofile-instr-generate -fcoverage-mapping
参数:
1 2
| # Step 1: Compile with coverage enabled % clang++ -fprofile-instr-generate -fcoverage-mapping foo.cc -o foo
|
可以将未加入覆盖率信息插桩的代码与加入的相互链接,只不过未插桩的不会计入覆盖率信息。
可以加入-coverage-mcdc
参数来添加Modified Condition/Decision Coverage(MC/DC)覆盖率统计方法。
运行插桩程序
运行插桩程序,程序退出后会保存raw profile到环境变量LLVM_PROFILE_FILE
目录下,默认保存到default.profraw
文件。
查看覆盖率报告
1 2
| Step 3(a): Index the raw profile. $ llvm-profdata merge -sparse foo.profraw -o foo.profdata
|
showLineNumbers1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ❯ llvm-cov show ./foo -instr-profile=foo.profdata 1| |/************************************************************************* 2| | > File Name: foo.cc 3| | > Author: eutopia 4| | > Mail: 2715417602@qq.com 5| | > Created Time: Mon Aug 4 17:24:37 2025 6| | ************************************************************************/ 7| | 8| 20|#define BAR(x) ((x) || (x)) 9| 2|template <typename T> void foo(T x) { 10| 22| for (unsigned I = 0; I < 10; ++I) { BAR(I); } 11| 2|} ------------------ | _Z3fooIiEvT_: | 9| 1|template <typename T> void foo(T x) { | 10| 11| for (unsigned I = 0; I < 10; ++I) { BAR(I); } | 11| 1|} ------------------ | _Z3fooIfEvT_: | 9| 1|template <typename T> void foo(T x) { | 10| 11| for (unsigned I = 0; I < 10; ++I) { BAR(I); } | 11| 1|} ------------------ 12| 1|int main() { 13| 1| foo<int>(0); 14| 1| foo<float>(0); 15| 1| return 0; 16| 1|}
|
查看报告:
1 2 3 4 5 6
| ❯ llvm-cov report ./foo --instr-profile=foo.profdata Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /home/bronya/test/coverage/foo.cc 8 0 100.00% 2 0 100.00% 8 0 100.00% 6 1 83.33% ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- TOTAL 8 0 100.00% 2 0 100.00% 8 0 100.00% 6 1 83.33%
|
后面的不太重要,暂时先不写了,可以阅读源链接
注:
SanitizerCoverage中关于边(Edge Coverage)的解释
参考链接
https://clang.llvm.org/docs/SourceBasedCodeCoverage.html