- fsaniize -coverage=trace-pc和trace-pc-guard有什么区别?



最近我一直在研究Clang消毒液。我发现标志-fsanitize-coverage可以是trace-pctrace-pc-guard。根据官方文件(tracingpcs with guards, tracingpcs),两者都可以在每个边插入存根函数(__sanitizer_cov_trace_pc()__sanitizer_cov_trace_pc_guard())。但是,它们之间有什么区别呢?

在我看来,trace-pc-guard只是trace-pc的一个更新的替代品。而trace-pc回调调用时没有进一步的信息,trace-pc-guard接收到唯一标识当前函数/基本块/边缘的保护值,反映在它们的签名中,可以用来禁用对各自调用者的跟踪(通过设置*guard=0):

  • void __sanitizer_cov_trace_pc();

  • void __sanitizer_cov_trace_pc_guard(uint32_t *guard);

如果您查看检测的源代码,您可以看到guard变量的传递似乎是它们唯一的区别:

// 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();
}
/* ... */
}

引入这些选项的提交也添加了一些解释:

  • -fsanitize-coverage=trace-pc

    d4590c7304575 (Wed Feb 17 21:34:43 2016 +0000)

    [sanitizer-coverage] implementation - fsanitizer -coverage=trace-pc。这类似于trace-bb,但具有不同的API。我们已经在GCC中为Linux内核模糊测试使用了等效标志。我们也可以在AFL中使用这个标志

  • -fsanitize-coverage=trace-pc-guard

    da718e55cf0bd (Wed Sep 14 01:39:35 2016 +0000)

    [sanitizer-coverage]添加了另一种类型的覆盖率检测:trace-pc-guard。目的是最终用这个替换所有的{bool覆盖,8位计数器,trace-pc}。

不幸的是,我不知道为什么trace-pc被用于内核模糊测试(如CoverageSanitizer文档所提到的)而不是trace-pc-guard-也许它只是为了兼容"遗留"代码工具?

最新更新