Recently I have been studying the Clang sanitizer. I find the flag -fsanitize-coverage
can be trace-pc
or trace-pc-guard
. According to the official document(Tracing PCs with guards, Tracing PCs), both can insert stub functions(__sanitizer_cov_trace_pc()
and __sanitizer_cov_trace_pc_guard()
) on every edges. But, what is the difference between them?

- 21
- 2
1 Answers
It seems to me that trace-pc-guard
is simply a newer alternative to trace-pc
. Whereas the trace-pc
callback is called with no further information, the trace-pc-guard
receives the guard value which uniquely identifies the current function / basic block / edge as reflected in their signatures and can be used to disable tracking of the respective caller (by setting *guard=0):
void __sanitizer_cov_trace_pc();
void __sanitizer_cov_trace_pc_guard(uint32_t *guard);
If you look at the source code for the instrumentation, you can see that the passing of the guard variable seems to be their only difference:
// llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
void ModuleSanitizerCoverage::InjectCoverageAtBlock(
Function &F,
BasicBlock &BB,
size_t Idx,
bool IsLeafFunc) {
/* ... */
if (Options.TracePC) {
IRB.CreateCall(SanCovTracePC)
->setCannotMerge(); // gets the PC using GET_CALLER_PC.
}
if (Options.TracePCGuard) {
auto GuardPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(IntptrTy, Idx * 4)),
Int32PtrTy);
IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
}
/* ... */
}
The commits that introduced the options also add a bit of explanation:
-fsanitize-coverage=trace-pc
d4590c7304575 (Wed Feb 17 21:34:43 2016 +0000)
[sanitizer-coverage] implement -fsanitize-coverage=trace-pc. This is similar to trace-bb, but has a different API. We already use the equivalent flag in GCC for Linux kernel fuzzing. We may be able to use this flag with AFL too
-fsanitize-coverage=trace-pc-guard
da718e55cf0bd (Wed Sep 14 01:39:35 2016 +0000)
[sanitizer-coverage] add yet another flavour of coverage instrumentation: trace-pc-guard. The intent is to eventually replace all of {bool coverage, 8bit-counters, trace-pc} with just this one.
Unfortunately, I do not know why trace-pc
is used for kernel fuzzing (as mentioned by the CoverageSanitizer documentation) instead of trace-pc-guard
- maybe it's just for compatibility of 'legacy' code instrumentation?

- 363
- 3
- 16