Official agent skill

Coverage Analysis

by trailofbits in trailofbits/skills

Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output.

OfficialCC-BY-SA-4.0Auto-check passedSecurity

Install Coverage Analysis

skills CLI
$ npx skills add trailofbits/skills --skill coverage-analysis -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install trailofbits/skills coverage-analysis --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/testing-handbook-skills/skills/coverage-analysis .claude/skills/coverage-analysis && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
coverage-analysis
GitHub stars
7.4k
Token cost
~5.3k tokens
SKILL.md length
1,447 words
Files
3 (incl. assets)
Skills in repo
79
Repo updated
First seen
Licence
CC-BY-SA-4.0

At a glance

Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output.

  • Works in 5 steps: Build with Coverage Instrumentation → Create Execution Runtime (C/C++ only) → Execute on Corpus → …
  • A fuzzer plateaus
  • SKILL.md covers Overview, When to Apply, Quick Reference and Ideal Coverage Workflow, plus 7 more sections
  • Calls cargo, rustc and cmake

What it does

Coverage Analysis is an agent skill from trailofbits/skills, published by the product's own GitHub organization. Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output. Covers baselining a new campaign, reading coverage reports, and turning uncovered regions into harness, seed, or dictionary work. Use when a fuzzer plateaus, when judging whether a harness is effective, after changing a harness, or when asking why some code is never reached.

Its SKILL.md is about 5.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including assets (for example `agents/openai.yaml`).

It sits in Security, covering Fuzzing and Test coverage. The repository describes itself as: Trail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows. The licence is CC-BY-SA-4.0.

When your agent uses it

  • A fuzzer plateaus
  • Judging whether a harness is effective
  • After changing a harness
  • Asking why some code is never reached

Example prompts

  • “Use the coverage-analysis skill to measure and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage…”
  • “/coverage-analysis”

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Build with Coverage Instrumentation
  2. Create Execution Runtime (C/C++ only)
  3. Execute on Corpus
  4. Process Coverage Data
  5. Analyze Results

What it can do on your machine

Read from SKILL.md and the folder at commit 82fe822. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • cargo
    • rustc
    • cmake
    • uv

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • arxiv.org
    • clang.llvm.org
    • llvm.org
    • gcovr.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Coverage Analysis loads about 5.3k tokens when it runs. Until then it costs about 104 tokens; SKILL.md has 1,447 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~104
When it runs · the whole SKILL.md, loaded when a task matches
~5.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from trailofbits/skills at commit 82fe822, republished under its CC-BY-SA-4.0 licence (© trailofbits). 1,447 words, ~5,251 tokens.

Download SKILL.mdSave it as .claude/skills/coverage-analysis/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
coverage-analysis
description
Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output. Covers baselining a new campaign, reading coverage reports, and turning uncovered regions into harness, seed, or dictionary work. Use when a fuzzer plateaus, when judging whether a harness is effective, after changing a harness, or when asking why some code is never reached.
type
technique

Coverage Analysis

Coverage analysis is essential for understanding which parts of your code are exercised during fuzzing. It helps identify fuzzing blockers like magic value checks and tracks the effectiveness of harness improvements over time.

Overview

Code coverage during fuzzing serves two critical purposes:

  1. Assessing harness effectiveness: Understand which parts of your application are actually executed by your fuzzing harnesses
  2. Tracking fuzzing progress: Monitor how coverage changes when updating harnesses, fuzzers, or the system under test (SUT)

Coverage is a proxy for fuzzer capability and performance. While coverage is not ideal for measuring fuzzer performance in absolute terms, it reliably indicates whether your harness works effectively in a given setup.

Key Concepts
ConceptDescription
Coverage instrumentationCompiler flags that track which code paths are executed
Corpus coverageCoverage achieved by running all test cases in a fuzzing corpus
Magic value checksHard-to-discover conditional checks that block fuzzer progress
Coverage-guided fuzzingFuzzing strategy that prioritizes inputs that discover new code paths
Coverage reportVisual or textual representation of executed vs. unexecuted code

When to Apply

Apply this technique when:

  • Starting a new fuzzing campaign to establish a baseline
  • Fuzzer appears to plateau without finding new paths
  • After harness modifications to verify improvements
  • When migrating between different fuzzers
  • Identifying areas requiring dictionary entries or seed inputs
  • Debugging why certain code paths aren't reached

Skip this technique when:

  • Fuzzing campaign is actively finding crashes
  • Coverage infrastructure isn't set up yet
  • Working with extremely large codebases where full coverage reports are impractical
  • Fuzzer's internal coverage metrics are sufficient for your needs

Quick Reference

TaskCommand/Pattern
LLVM coverage instrumentation (C/C++)-fprofile-instr-generate -fcoverage-mapping
GCC coverage instrumentation-ftest-coverage -fprofile-arcs
cargo-fuzz coverage (Rust)cargo +nightly fuzz coverage <target>
Generate LLVM profile datallvm-profdata merge -sparse file.profraw -o file.profdata
LLVM coverage reportllvm-cov report ./binary -instr-profile=file.profdata
LLVM HTML reportllvm-cov show ./binary -instr-profile=file.profdata -format=html -output-dir html/
gcovr HTML reportgcovr --html-details -o coverage.html

Ideal Coverage Workflow

The following workflow represents best practices for integrating coverage analysis into your fuzzing campaigns:

[Fuzzing Campaign]
       |
       v
[Generate Corpus]
       |
       v
[Coverage Analysis]
       |
       +---> Coverage Increased? --> Continue fuzzing with larger corpus
       |
       +---> Coverage Decreased? --> Fix harness or investigate SUT changes
       |
       +---> Coverage Plateaued? --> Add dictionary entries or seed inputs

Key principle: Use the corpus generated after each fuzzing campaign to calculate coverage, rather than real-time fuzzer statistics. This approach provides reproducible, comparable measurements across different fuzzing tools.

Step-by-Step

Step 1: Build with Coverage Instrumentation

Choose your instrumentation method based on toolchain:

LLVM/Clang (C/C++):

bash
clang++ -fprofile-instr-generate -fcoverage-mapping \
  -O2 -DNO_MAIN \
  main.cc harness.cc execute-rt.cc -o fuzz_exec

GCC (C/C++):

bash
g++ -ftest-coverage -fprofile-arcs \
  -O2 -DNO_MAIN \
  main.cc harness.cc execute-rt.cc -o fuzz_exec_gcov

Rust:

bash
rustup toolchain install nightly --component llvm-tools-preview
cargo +nightly fuzz coverage fuzz_target_1
Step 2: Create Execution Runtime (C/C++ only)

For C/C++ projects, create a runtime that executes your corpus:

cpp
// execute-rt.cc
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdint.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

void load_file_and_test(const char *filename) {
    FILE *file = fopen(filename, "rb");
    if (file == NULL) {
        printf("Failed to open file: %s\n", filename);
        return;
    }

    fseek(file, 0, SEEK_END);
    long filesize = ftell(file);
    rewind(file);

    uint8_t *buffer = (uint8_t*) malloc(filesize);
    if (buffer == NULL) {
        printf("Failed to allocate memory for file: %s\n", filename);
        fclose(file);
        return;
    }

    long read_size = (long) fread(buffer, 1, filesize, file);
    if (read_size != filesize) {
        printf("Failed to read file: %s\n", filename);
        free(buffer);
        fclose(file);
        return;
    }

    LLVMFuzzerTestOneInput(buffer, filesize);

    free(buffer);
    fclose(file);
}

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("Usage: %s <directory>\n", argv[0]);
        return 1;
    }

    DIR *dir = opendir(argv[1]);
    if (dir == NULL) {
        printf("Failed to open directory: %s\n", argv[1]);
        return 1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_REG) {
            char filepath[1024];
            snprintf(filepath, sizeof(filepath), "%s/%s", argv[1], entry->d_name);
            load_file_and_test(filepath);
        }
    }

    closedir(dir);
    return 0;
}
Step 3: Execute on Corpus

LLVM (C/C++):

bash
LLVM_PROFILE_FILE=fuzz.profraw ./fuzz_exec corpus/

GCC (C/C++):

bash
./fuzz_exec_gcov corpus/

Rust: Coverage data is automatically generated when running cargo fuzz coverage.

Step 4: Process Coverage Data

LLVM:

bash
# Merge raw profile data
llvm-profdata merge -sparse fuzz.profraw -o fuzz.profdata

# Generate text report
llvm-cov report ./fuzz_exec \
  -instr-profile=fuzz.profdata \
  -ignore-filename-regex='harness.cc|execute-rt.cc'

# Generate HTML report
llvm-cov show ./fuzz_exec \
  -instr-profile=fuzz.profdata \
  -ignore-filename-regex='harness.cc|execute-rt.cc' \
  -format=html -output-dir fuzz_html/

GCC with gcovr:

bash
# Install gcovr (uv manages the isolated environment)
uv tool install gcovr
export PATH="$HOME/.local/bin:$PATH"   # uv's tool bin, if not already present

# Generate report
gcovr --gcov-executable "llvm-cov gcov" \
  --exclude harness.cc --exclude execute-rt.cc \
  --root . --html-details -o coverage.html

Rust:

bash
# Install required tools
cargo install cargo-binutils rustfilt

# Create HTML generation script
cat <<'EOF' > ./generate_html
#!/bin/sh
if [ $# -lt 1 ]; then
    echo "Error: Name of fuzz target is required."
    echo "Usage: $0 fuzz_target [sources...]"
    exit 1
fi
FUZZ_TARGET="$1"
shift
SRC_FILTER="$@"
TARGET=$(rustc -vV | sed -n 's|host: ||p')
cargo +nightly cov -- show -Xdemangler=rustfilt \
  "target/$TARGET/coverage/$TARGET/release/$FUZZ_TARGET" \
  -instr-profile="fuzz/coverage/$FUZZ_TARGET/coverage.profdata" \
  -show-line-counts-or-regions -show-instantiations \
  -format=html -o fuzz_html/ $SRC_FILTER
EOF
chmod +x ./generate_html

# Generate HTML report
./generate_html fuzz_target_1 src/lib.rs
Step 5: Analyze Results

Review the coverage report to identify:

  • Uncovered code blocks: Areas that may need better seed inputs or dictionary entries
  • Magic value checks: Conditional statements with hardcoded values that block progress
  • Dead code: Functions that may not be reachable through your harness
  • Coverage changes: Compare against baseline to track improvements or regressions

Common Patterns

Pattern: Identifying Magic Values

Problem: Fuzzer cannot discover paths guarded by magic value checks.

Coverage reveals:

cpp
// Coverage shows this block is never executed
if (buf == 0x7F454C46) {  // ELF magic number
    // start parsing buf
}

Solution: Add magic values to dictionary file:

# magic.dict
"\x7F\x45\x4C\x46"
Pattern: Handling Crashing Inputs

Problem: Coverage generation fails when corpus contains crashing inputs.

Before:

bash
./fuzz_exec corpus/  # Crashes on bad input, no coverage generated

After:

cpp
// Fork before executing to isolate crashes
int main(int argc, char **argv) {
    // ... directory opening code ...

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_REG) {
            pid_t pid = fork();
            if (pid == 0) {
                // Child process - crash won't affect parent
                char filepath[1024];
                snprintf(filepath, sizeof(filepath), "%s/%s", argv[1], entry->d_name);
                load_file_and_test(filepath);
                exit(0);
            } else {
                // Parent waits for child
                waitpid(pid, NULL, 0);
            }
        }
    }
}
Pattern: CMake Integration

Use Case: Adding coverage builds to CMake projects.

cmake
project(FuzzingProject)
cmake_minimum_required(VERSION 3.0)

# Main binary
add_executable(program main.cc)

# Fuzzing binary
add_executable(fuzz main.cc harness.cc)
target_compile_definitions(fuzz PRIVATE NO_MAIN=1)
target_compile_options(fuzz PRIVATE -g -O2 -fsanitize=fuzzer)
target_link_libraries(fuzz -fsanitize=fuzzer)

# Coverage execution binary
add_executable(fuzz_exec main.cc harness.cc execute-rt.cc)
target_compile_definitions(fuzz_exec PRIVATE NO_MAIN)
target_compile_options(fuzz_exec PRIVATE -O2 -fprofile-instr-generate -fcoverage-mapping)
target_link_libraries(fuzz_exec -fprofile-instr-generate)

Build:

bash
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .
cmake --build . --target fuzz_exec

Advanced Usage

Tips and Tricks
TipWhy It Helps
Use LLVM 18+ with -show-directory-coverageOrganizes large reports by directory structure instead of flat file list
Export to lcov format for better HTMLllvm-cov export -format=lcov + genhtml provides cleaner per-file reports
Compare coverage across campaignsStore .profdata files with timestamps to track progress over time
Filter harness code from reportsUse -ignore-filename-regex to focus on SUT coverage only
Automate coverage in CI/CDGenerate coverage reports automatically after scheduled fuzzing runs
Use gcovr 5.1+ for Clang 14+Older gcovr versions have compatibility issues with recent LLVM
Incremental Coverage Updates

GCC's gcov instrumentation incrementally updates .gcda files across multiple runs. This is useful for tracking coverage as you add test cases:

bash
# First run
./fuzz_exec_gcov corpus_batch_1/
gcovr --html coverage_v1.html

# Second run (adds to existing coverage)
./fuzz_exec_gcov corpus_batch_2/
gcovr --html coverage_v2.html

# Start fresh
gcovr --delete  # Remove .gcda files
./fuzz_exec_gcov corpus/
Handling Large Codebases

For projects with hundreds of source files:

  1. Filter by prefix: Only generate reports for relevant directories

    bash
    llvm-cov show ./fuzz_exec -instr-profile=fuzz.profdata /path/to/src/
  2. Use directory coverage: Group by directory to reduce clutter (LLVM 18+)

    bash
    llvm-cov show -show-directory-coverage -format=html -output-dir html/
  3. Generate JSON for programmatic analysis:

    bash
    llvm-cov export -format=lcov > coverage.json
Differential Coverage

Compare coverage between two fuzzing campaigns:

bash
# Campaign 1
LLVM_PROFILE_FILE=campaign1.profraw ./fuzz_exec corpus1/
llvm-profdata merge -sparse campaign1.profraw -o campaign1.profdata

# Campaign 2
LLVM_PROFILE_FILE=campaign2.profraw ./fuzz_exec corpus2/
llvm-profdata merge -sparse campaign2.profraw -o campaign2.profdata

# Compare
llvm-cov show ./fuzz_exec \
  -instr-profile=campaign2.profdata \
  -instr-profile=campaign1.profdata \
  -show-line-counts-or-regions

Anti-Patterns

Anti-PatternProblemCorrect Approach
Using fuzzer-reported coverage for comparisonsDifferent fuzzers calculate coverage differently, making cross-tool comparison meaninglessUse dedicated coverage tools (llvm-cov, gcovr) for reproducible measurements
Generating coverage with optimizations-O3 optimizations can eliminate code, making coverage misleadingUse -O2 or -O0 for coverage builds
Not filtering harness codeHarness coverage inflates numbers and obscures SUT coverageUse -ignore-filename-regex or --exclude to filter harness files
Mixing LLVM and GCC instrumentationIncompatible formats cause parsing failuresStick to one toolchain for coverage builds
Ignoring crashing inputsCrashes prevent coverage generation, hiding real coverage dataFix crashes first, or use process forking to isolate them
Not tracking coverage over timeOne-time coverage checks miss regressions and improvementsStore coverage data with timestamps and track trends

Tool-Specific Guidance

libFuzzer

libFuzzer uses LLVM's SanitizerCoverage by default for guiding fuzzing, but you need separate instrumentation for generating reports.

Build for coverage:

bash
clang++ -fprofile-instr-generate -fcoverage-mapping \
  -O2 -DNO_MAIN \
  main.cc harness.cc execute-rt.cc -o fuzz_exec

Execute corpus and generate report:

bash
LLVM_PROFILE_FILE=fuzz.profraw ./fuzz_exec corpus/
llvm-profdata merge -sparse fuzz.profraw -o fuzz.profdata
llvm-cov show ./fuzz_exec -instr-profile=fuzz.profdata -format=html -output-dir html/

Integration tips:

  • Don't use -fsanitize=fuzzer for coverage builds (it conflicts with profile instrumentation)
  • Reuse the same harness function (LLVMFuzzerTestOneInput) with a different main function
  • Use the -ignore-filename-regex flag to exclude harness code from coverage reports
  • Consider using llvm-cov's -show-instantiation flag for template-heavy C++ code
Show full SKILL.md (552 more words)Show less
AFL++

AFL++ provides its own coverage feedback mechanism, but for detailed reports use standard LLVM/GCC tools.

Build for coverage with LLVM:

bash
clang++ -fprofile-instr-generate -fcoverage-mapping \
  -O2 main.cc harness.cc execute-rt.cc -o fuzz_exec

Build for coverage with GCC:

bash
AFL_USE_ASAN=0 afl-gcc -ftest-coverage -fprofile-arcs \
  main.cc harness.cc execute-rt.cc -o fuzz_exec_gcov

Execute and generate report:

bash
# LLVM approach
LLVM_PROFILE_FILE=fuzz.profraw ./fuzz_exec afl_output/queue/
llvm-profdata merge -sparse fuzz.profraw -o fuzz.profdata
llvm-cov report ./fuzz_exec -instr-profile=fuzz.profdata

# GCC approach
./fuzz_exec_gcov afl_output/queue/
gcovr --html-details -o coverage.html

Integration tips:

  • Don't use AFL++'s instrumentation (afl-clang-fast) for coverage builds
  • Use standard compilers with coverage flags instead
  • AFL++'s queue/ directory contains your corpus
  • AFL++'s built-in coverage statistics are useful for real-time monitoring but not for detailed analysis
cargo-fuzz (Rust)

cargo-fuzz provides built-in coverage generation using LLVM tools.

Install prerequisites:

bash
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils rustfilt

Generate coverage data:

bash
cargo +nightly fuzz coverage fuzz_target_1

Create HTML report script:

bash
cat <<'EOF' > ./generate_html
#!/bin/sh
FUZZ_TARGET="$1"
shift
SRC_FILTER="$@"
TARGET=$(rustc -vV | sed -n 's|host: ||p')
cargo +nightly cov -- show -Xdemangler=rustfilt \
  "target/$TARGET/coverage/$TARGET/release/$FUZZ_TARGET" \
  -instr-profile="fuzz/coverage/$FUZZ_TARGET/coverage.profdata" \
  -show-line-counts-or-regions -show-instantiations \
  -format=html -o fuzz_html/ $SRC_FILTER
EOF
chmod +x ./generate_html

Generate report:

bash
./generate_html fuzz_target_1 src/lib.rs

Integration tips:

  • Always use the nightly toolchain for coverage
  • The -Xdemangler=rustfilt flag makes function names readable
  • Filter by source files (e.g., src/lib.rs) to focus on crate code
  • Use -show-line-counts-or-regions and -show-instantiations for better Rust-specific output
  • Corpus is located in fuzz/corpus/<target>/
honggfuzz

honggfuzz works with standard LLVM/GCC coverage instrumentation.

Build for coverage:

bash
# Use standard compiler, not honggfuzz compiler
clang -fprofile-instr-generate -fcoverage-mapping \
  -O2 harness.c execute-rt.c -o fuzz_exec

Execute corpus:

bash
LLVM_PROFILE_FILE=fuzz.profraw ./fuzz_exec honggfuzz_workspace/

Integration tips:

  • Don't use hfuzz-clang for coverage builds
  • honggfuzz corpus is typically in a workspace directory
  • Use the same LLVM workflow as libFuzzer

Troubleshooting

IssueCauseSolution
error: no profile data availableProfile wasn't generated or wrong pathVerify LLVM_PROFILE_FILE was set and .profraw file exists
Failed to load coverageMismatch between binary and profile dataRebuild binary with same flags used during execution
Coverage reports show 0%Wrong binary used for report generationUse the instrumented binary, not the fuzzing binary
no_working_dir_found error (gcovr).gcda files in unexpected locationAdd --gcov-ignore-errors=no_working_dir_found flag
Crashes prevent coverage generationCorpus contains crashing inputsFilter crashes or use forking approach to isolate failures
Coverage decreases after harness changeHarness now skips certain code pathsReview harness logic; may need to support more input formats
HTML report is flat file listUsing older LLVM versionUpgrade to LLVM 18+ and use -show-directory-coverage
incompatible instrumentationMixing LLVM and GCC coverageRebuild everything with same toolchain
Tools That Use This Technique
SkillHow It Applies
libfuzzerUses SanitizerCoverage for feedback; coverage analysis evaluates harness effectiveness
aflppUses edge coverage for feedback; detailed analysis requires separate instrumentation
cargo-fuzzBuilt-in cargo fuzz coverage command for Rust projects
honggfuzzUses edge coverage; analyze with standard LLVM/GCC tools
SkillRelationship
fuzz-harness-writingCoverage reveals which code paths harness reaches; guides harness improvements
fuzzing-dictionariesCoverage identifies magic value checks that need dictionary entries
corpus-managementCoverage analysis helps curate corpora by identifying redundant test cases
sanitizersCoverage helps verify sanitizer-instrumented code is actually executed

Resources

Key External Resources

LLVM Source-Based Code Coverage Comprehensive guide to LLVM's profile instrumentation, including advanced features like branch coverage, region coverage, and integration with existing build systems. Covers compiler flags, runtime behavior, and profile data formats.

llvm-cov Command Guide Detailed CLI reference for llvm-cov commands including show, report, and export. Documents all filtering options, output formats, and integration with llvm-profdata.

gcovr Documentation Complete guide to gcovr tool for generating coverage reports from gcov data. Covers HTML themes, filtering options, multi-directory projects, and CI/CD integration patterns.

SanitizerCoverage Documentation Low-level documentation for LLVM's SanitizerCoverage instrumentation. Explains inline 8-bit counters, PC tables, and how fuzzers use coverage feedback for guidance.

On the Evaluation of Fuzzer Performance Research paper examining limitations of coverage as a fuzzing performance metric. Argues for more nuanced evaluation methods beyond simple code coverage percentages.

Video Resources

Not applicable - coverage analysis is primarily a tooling and workflow topic best learned through documentation and hands-on practice.

© trailofbits, CC-BY-SA-4.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (assets) in plugins/testing-handbook-skills/skills/coverage-analysis of trailofbits/skills.

  • SKILL.md
  • agents/openai.yaml
  • assets/trail-of-bits-mark.svg

Open the folder on GitHubat commit 82fe822

Compare with similar skills

Coverage Analysis next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Coverage Analysis compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Coverage Analysis this skilltrailofbits/skills7.4k—~5.3kAutomated safety check: PassCC-BY-SA-4.0
703 Technologies Fuzzing Testingjabrena/plinth446—~874Automated safety check: PassApache-2.0
Golang Testingantoniopaya22/go-rest-template1729 repos~4.2kAutomated safety check: PassNone
Golang Testingunxed/f42411 repos~4.5kAutomated safety check: PassMIT
Golang Testingaffaan-m/ECC275k1 repos~4.3kAutomated safety check: PassMIT
Fizzpashov/skills1.2k2 repos~11kAutomated safety check: PassMIT

Similar skills

  • A skill your agent uses when you need to add or review fuzz testing for Java APIs with CATS — including contract-driven negative testing, malformed payload validation, boundary input exploration, CI…

    446 GitHub stars~874 tokensUpdated today
    Testing & QAAuto-check passed
  • Golang Testing

    antoniopaya22/go-rest-template

    Go testing patterns including table-driven tests, subtests, benchmarks, fuzzing, and test coverage.

    172 GitHub starsUsed in 9 repos~4.2k tokens
    Testing & QAAuto-check passed
  • Production-ready Golang tests — table-driven tests, testify suites and mocks, parallel tests, fuzzing, fixtures, goroutine leak detection with goleak, snapshot testing, code coverage, integration…

    241 GitHub starsUsed in 1 repo~4.5k tokens
    Testing & QAAuto-check passed
  • Golang Testing

    affaan-m/ECC

    Table-driven testler, subtestler, benchmark'lar, fuzzing ve test coverage içeren Go test desenleri.

    275k GitHub starsUsed in 1 repo~4.3k tokens
    Testing & QAAuto-check passed
  • Fizz

    pashov/skills

    Generate Echidna/Medusa-compatible Solidity fuzz suites from Foundry or Hardhat projects.

    1.2k GitHub starsUsed in 2 repos~11k tokens
    SecurityAuto-check passed
  • Fizz Sync

    pashov/skills

    Reconcile an existing Fizz harness with a changed source tree.

    1.2k GitHub starsUsed in 2 repos~3.9k tokens
    SecurityAuto-check passed

More from trailofbits/skills

All 79 skills in this repo
  • Code Graph Mermaid Diagrams

    trailofbits/skills

    Official

    Generates Mermaid diagrams from Trailmark code graphs, including call graphs, class hierarchies, module dependency maps, complexity heatmaps and attack surface data flows.

    7.4k GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed
  • CodeQL Security Scan

    trailofbits/skills

    Official

    Scans a codebase for vulnerabilities with CodeQL's data flow and taint tracking in run-all or important-only modes, including data extensions for project-specific sources and sinks.

    7.4k GitHub stars~4.6k tokensUpdated today
    Auto-check: notes
  • Trailmark Graph Evolution

    trailofbits/skills

    Official

    Compares Trailmark code graphs at two snapshots, such as commits, tags or directories, to surface attack paths, blast radius and taint changes that text diffs miss.

    7.4k GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Let Fate Decide

    trailofbits/skills

    Official

    Draws a 12 Houses tarot spread to break ties when a request is vague or casually delegated, then reads the cards to pick the next step.

    7.4k GitHub stars~2.5k tokensUpdated today
    Auto-check: notes
  • Burp Suite Project Parser

    trailofbits/skills

    Official

    Searches and extracts data from Burp Suite project files on the command line: regex searches over responses, audit findings, proxy history and site map data.

    7.4k GitHub starsUsed in 4 repos~4.2k tokens
    Auto-check: notes
  • Semgrep Security Scan

    trailofbits/skills

    Official

    Detects languages, proposes rulesets for approval, then runs the approved Semgrep scan across a codebase and merges the output into one SARIF file.

    7.4k GitHub stars~3.7k tokensUpdated today
    Auto-check: notes

Categories

Questions about Coverage Analysis

What does Coverage Analysis do?

Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output. Coverage Analysis is an agent skill from trailofbits/skills, published by the product's own GitHub organization. Measures and interprets what a fuzzing campaign actually reaches, using llvm-cov, lcov, or a fuzzer's own coverage output.

When should I use Coverage Analysis?

Coverage Analysis fits situations like: A fuzzer plateaus; judging whether a harness is effective; after changing a harness; asking why some code is never reached.

How do I install Coverage Analysis in Claude Code?

Run `npx skills add trailofbits/skills --skill coverage-analysis -a claude-code`. Or copy the skill folder (plugins/testing-handbook-skills/skills/coverage-analysis in trailofbits/skills) into .claude/skills/coverage-analysis in your project. Claude Code loads it when a task matches its description.

How do I install Coverage Analysis in Codex?

Run `npx skills add trailofbits/skills --skill coverage-analysis -a codex`. Or copy the skill folder (plugins/testing-handbook-skills/skills/coverage-analysis in trailofbits/skills) into .agents/skills/coverage-analysis in your project. Codex loads it when a task matches its description.

Can I use Coverage Analysis in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add trailofbits/skills --skill coverage-analysis -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/coverage-analysis, .gemini/skills/coverage-analysis, .github/skills/coverage-analysis and .opencode/skills/coverage-analysis in your project.

What does Coverage Analysis need to run?

Going by SKILL.md and its folder, Coverage Analysis needs the command-line tools its instructions call (cargo, rustc, cmake and uv).

Does Coverage Analysis access the network?

SKILL.md names 4 domains. As links in the text: arxiv.org, clang.llvm.org, llvm.org and gcovr.com. This is read from the text; nothing was executed.

Is Coverage Analysis safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Coverage Analysis use?

Coverage Analysis is published under the CC-BY-SA-4.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Coverage Analysis use?

About 5.3k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Coverage Analysis?

Skills that share tags, products or a category with Coverage Analysis: 703 Technologies Fuzzing Testing (jabrena/plinth, 446 stars), Golang Testing (antoniopaya22/go-rest-template, 172 stars), Golang Testing (unxed/f4, 241 stars) and Golang Testing (affaan-m/ECC, 275k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Coverage Analysis?

trailofbits (a GitHub organization, an official publisher) maintains it in trailofbits/skills, which has 7,420 GitHub stars. The repository holds 79 skills in this directory. The repository was last updated on October 7, 2026.

Source: trailofbits/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.