2

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?

SeekaMoon
  • 21
  • 2

1 Answers1

0

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?

Jonas Möller
  • 363
  • 3
  • 16