You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Clang+libFuzzer做模糊测试时为何显示代码覆盖率为0?

libFuzzer 覆盖率全0但程序已崩溃的问题排查与解决

问题描述

使用LLVM libFuzzer和Clang进行模糊测试时,程序按预期触发崩溃,但生成的覆盖率报告显示所有代码行命中数为0。测试代码为经典的嵌套分支示例:

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
    if (size > 0 && data[0] == 'H')
    {
        if (size > 1 && data[1] == 'I')
        {
            if (size > 2 && data[2] == '!')
            {
                int *foo = (int *)44;
                *foo = 5;
            }
        }
    }
    return 0;
}

编译命令:

clang -g -O1 -fsanitize=fuzzer -fprofile-instr-generate -fcoverage-mapping FuzzingApp.cpp -o FuzzingApp.exe

运行程序崩溃后生成default.profraw,经llvm-profdata merge处理后,llvm-cov show输出所有行覆盖率为0,且在Clang 17.0.3(VS分发版)和18.1.8(官方最新版)中均存在该问题。

根本原因

Clang的-fprofile-instr-generate覆盖率数据默认仅在进程正常退出时才会从内存缓冲区写入到.profraw文件。而libFuzzer在检测到崩溃(如非法内存访问)时,会直接通过信号终止进程,跳过了正常退出流程中的覆盖率数据刷新步骤,导致生成的.profraw文件为空或不包含有效执行数据,最终llvm-cov无法解析出正确的覆盖率。

解决方案

方案1:使用libFuzzer内置参数强制dump覆盖率

运行模糊测试程序时添加-dump_coverage=1参数,该参数会让libFuzzer在崩溃前主动将覆盖率数据写入文件:

FuzzingApp.exe -dump_coverage=1

重新生成.profraw后,再执行后续的llvm-profdata merge和llvm-cov show命令,即可看到正确的覆盖率统计。

方案2:在代码中手动触发覆盖率刷新

在触发崩溃的代码前,调用Clang提供的__llvm_profile_write_file()函数强制写入覆盖率数据:

#include <cstdint>

// 声明覆盖率写入函数
extern "C" void __llvm_profile_write_file(void);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
    if (size > 0 && data[0] == 'H')
    {
        if (size > 1 && data[1] == 'I')
        {
            if (size > 2 && data[2] == '!')
            {
                __llvm_profile_write_file(); // 崩溃前手动写入覆盖率
                int *foo = (int *)44;
                *foo = 5;
            }
        }
    }
    return 0;
}

重新编译并运行程序,生成的.profraw将包含完整的执行覆盖数据。

额外验证步骤

处理.profraw前,可通过以下命令确认文件是否包含有效数据:

llvm-profdata show default.profdata

若输出中包含函数LLVMFuzzerTestOneInput的覆盖信息,则说明数据有效。

内容的提问来源于stack exchange,提问作者Ian Brockbank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:02:34