blob: 07756b0cc7f98b748b97a0c6e6a248994f2f25f0 [file] [log] [blame]
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
# usage: fuzz-coverage.py [-h] corpus program srcdir builddir outdir
# Runs corpus (directory of testcases) against a program
# built with coverage, and produces a html report.
# The program should be built with --coverage -fprofile-abs-path
# -O0 may make the html report more legible?
# Requires lcov and https://github.com/mozilla/grcov
import argparse
import subprocess
import sys
from pathlib import Path
def run(args):
corpus = Path(args.corpus)
outdir = Path(args.outdir)
for c in Path(args.builddir).glob("**/*.gcda"):
print(f"Removed old coverage {c}", file=sys.stderr)
c.unlink()
print("Running corpus", file=sys.stderr)
for c in corpus.glob("*"):
c = c.open("rb").read()
subprocess.run([args.program], input=c)
print("Running grcov", file=sys.stderr)
outdir.mkdir(parents=True, exist_ok=True)
coverage_paths = [args.builddir]
lcov_file = outdir / "lcov.info"
subprocess.run(
[
"grcov",
"-b",
args.program,
"-o",
lcov_file,
"-t",
"lcov",
"-s",
args.srcdir,
]
+ coverage_paths,
check=True,
)
print("Running genhtml", file=sys.stderr)
subprocess.run(
[
"genhtml",
"-o",
outdir,
"--show-details",
"--highlight",
"--ignore-errors",
"source",
"--legend",
lcov_file,
],
check=True,
)
html = outdir / "index.html"
print(f"\n\nOutput is file://{html.absolute()}", file=sys.stderr)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("corpus", type=str, help="Corpus directory")
parser.add_argument("program", type=str, help="Target Program")
parser.add_argument("srcdir", type=str, help="Source directory")
parser.add_argument("builddir", type=str)
parser.add_argument("outdir", type=str)
args = parser.parse_args()
run(args)
if __name__ == "__main__":
main()