LLVM "continuous" coverage profiling hack^Wpatch
- Reply: Adrian Chadd : "Re: LLVM "continuous" coverage profiling hack^Wpatch"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 12 Oct 2026 19:16:14 UTC
INTRO:
======
Coverage profiling is where the compiler adds counters in the code so
one can tell which bits got executed how many times.
People should use it much more than they do.
Normally, the counters are written to a file by an atexit(3) handler
but that goes haywire in pretty much any unplain program.
The solution is to mmap(2) the memory for the counters, so that no
matter how the process expires, the counts are recorded for later
analysis.
For this to work, the counters must be page aligned in the ELF file.
CURRENT STATE OF AFFAIRS:
=========================
Somebody has hacked support for mmap(2) counters into LLVM on Apple
platforms, and they use an Apple-only lld(1) argument ("-sectalign")
to tell the loader to align the relevant ELF-sections.
They also added a comment to the effect that
"Support for Linux may be mostly complete but requires
testing, and support for Windows may require more extensive
changes: please get involved if you are interested in porting
this feature."
And seem to have left it there.
THE PATCH:
==========
I dont know what the proper way to implement this in FreeBSD is,
but the attached hack^Wpatch makes it work for me.
It uses the same code-path as Apple platforms for the mmap(2)'ery
and hardcodes the ELF segment names into lld.
The patch should be a no-op unless profiling is enabled.
I dont know if this patch is suitable as a local patch for FreeBSD
or if there is any reason to attempt to upstream it, and I dont
have the time spend to find out. If somebody wants to pick it
up, be my guest.
HOWTO:
======
Apply patch, recompile clang and lld. (or world).
Compile your code with
-fprofile-instr-generate -fcoverage-mapping
Create a directory for the count files:
rm -rf /tmp/GC
mkdir -p /tmp/GC
Set the environment var to point to that directory:
export LLVM_PROFILE_FILE=/tmp/GC/%p%c.profraw
The '%c' is the magic bit which enables "continous" aka mmap(2) mode.
Now run the program(s) you want tested.
./a.out
Then merge all the count files:
llvm-profdata merge -sparse /tmp/GC/* -o /tmp/gc.profdata
The data can be visualized with:
llvm-cov show ./a.out -instr-profile=/tmp/gc.profdata
Enjoy,
Poul-Henning
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.