Repository navigation
Measure fuzzing coverage beside test coverage - #652
Merged
Merged
Conversation
…gge.md) Nothing measured what the fuzz corpora reach, so there was no way to say where fuzzing adds to the tests and where it leaves untrusted-input code untouched. fuzz/coverage.sh runs hobbes-test and replays each harness's corpus once under Clang source-based coverage. coverage-compare.py then sorts every instrumented line into covered by both, by the tests only, by the fuzzers only, or by neither, per directory and per file, and counts the lines each harness reaches that nothing else does. The comparison needs the harnesses and hobbes-test linked against the same instrumented libhobbes. With Clang that was impossible, because BUILD_FUZZERS applies -fsanitize=fuzzer-no-link to the whole build, and hobbes-test then fails to link. The new FUZZ_STANDALONE option builds the harnesses as the standalone replay runners already used for compilers without libFuzzer, and leaves the rest of the build alone. Building those runners on macOS showed that standalone_main.C declared LLVMFuzzerInitialize as a weak undefined symbol. Apple's linker refuses that, so the three harnesses that do not define it (fregion-reader, type-decode, hog-session) never linked as standalone runners there. It is now a weak default definition, which a harness's own definition overrides on both ELF and Mach-O. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brianegge
enabled auto-merge
October 3, 2026 02:49
bingenito
approved these changes
Oct 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a way to measure which lines of hobbes the fuzz corpora reach, and to compare that line by line with what
hobbes-testreaches.What's added
fuzz/coverage.sh <build-dir> [corpora] [out]: runshobbes-test, replays each harness's corpus once (no mutation), and merges the profiles. It writes one lcov per profile plus a Markdown report.fuzz/coverage-compare.py: sorts every instrumented line into four bins: both, tests only, fuzzing only, or neither. It reports per directory and per file, and counts the lines each harness reaches that nothing else does.FUZZ_STANDALONECMake option: builds the harnesses as the existing standalone replay runners and doesn't apply-fsanitize=fuzzer-no-linkto the rest of the build. Without it, a ClangBUILD_FUZZERStree can't linkhobbes-test, so the tests and the harnesses could never share one instrumentedlibhobbes. The default libFuzzer configuration is unchanged.standalone_main.Cfix: it declaredLLVMFuzzerInitializeas a weak undefined symbol, which Apple's linker refuses. On macOS, fregion-reader, type-decode and hog-session therefore never linked as standalone runners. It's now a weak default definition that a harness's own definition overrides on both ELF and Mach-O.fuzz/README.mdsection: covers the setup and how to read the numbers.First results
These come from corpora grown locally for 10 minutes per harness (UBSan libFuzzer, macOS arm64), starting from the shipped seeds. OSS-Fuzz's corpus backups aren't public, so these numbers are a floor for fuzzing.
lib/hobbes/lang,readandparseall have similar shares from tests and from fuzzing.lib/hobbes/ipc(net.C,prepl.C) andlib/hobbes/dbhave 8–15% fuzzing coverage, against about 55–69% from the tests. These look like the next harnesses worth writing.These numbers use Clang source-based coverage, which counts lines differently from the gcov-based CI coverage report (72.3% on
main). Only compare them with each other.Testing
main): configured the coverage build, built all targets, and ranfuzz/coverage.shagainst the grown corpora. Every replay batch finished, andhobbes-testpassed under coverage.BUILD_FUZZERS=ONconfiguration still selects libFuzzer and appliesfuzzer-no-link.🤖 Generated with Claude Code