<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 11, 2017 at 7:05 PM, Vedant Kumar <span dir="ltr"><<a href="mailto:vsk@apple.com" target="_blank">vsk@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
You can simplify this a bit if libFuzzer has access to the profiling runtime.<br></blockquote><div><br></div><br>libFuzzer should be able to link w/ and w/o -fprofile-instr-generate, so these functions will need to be declared "weak"<br>But yes, thanks for the hint.<br>Next time I touch this code I'll simplify it as you suggest. <br>At this moment it is very experimental and the preliminary results are not promising,<br><div>so this code may not survive in the long term.  </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="gmail-h5"><br>
> On Aug 11, 2017, at 4:03 PM, Kostya Serebryany via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: kcc<br>
> Date: Fri Aug 11 16:03:22 2017<br>
> New Revision: 310771<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=310771&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=310771&view=rev</a><br>
> Log:<br>
> [libFuzzer] experimental support for Clang's coverage (fprofile-instr-generate), Linux-only<br>
><br>
> Added:<br>
>    llvm/trunk/lib/Fuzzer/<wbr>FuzzerClangCounters.cpp<br>
>    llvm/trunk/lib/Fuzzer/test/<wbr>fprofile-instr-generate.test<br>
> Modified:<br>
>    llvm/trunk/lib/Fuzzer/<wbr>CMakeLists.txt<br>
>    llvm/trunk/lib/Fuzzer/<wbr>FuzzerDefs.h<br>
>    llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.cpp<br>
>    llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.h<br>
><br>
> Modified: llvm/trunk/lib/Fuzzer/<wbr>CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=310771&r1=310770&r2=310771&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>CMakeLists.txt?rev=310771&r1=<wbr>310770&r2=310771&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/<wbr>CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/Fuzzer/<wbr>CMakeLists.txt Fri Aug 11 16:03:22 2017<br>
> @@ -31,6 +31,7 @@ endif()<br>
><br>
> if (LIBFUZZER_ENABLE)<br>
>   add_library(<wbr>LLVMFuzzerNoMainObjects OBJECT<br>
> +      FuzzerClangCounters.cpp<br>
>       FuzzerCrossOver.cpp<br>
>       FuzzerDriver.cpp<br>
>       FuzzerExtFunctionsDlsym.cpp<br>
><br>
> Added: llvm/trunk/lib/Fuzzer/<wbr>FuzzerClangCounters.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerClangCounters.cpp?rev=310771&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>FuzzerClangCounters.cpp?rev=<wbr>310771&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/<wbr>FuzzerClangCounters.cpp (added)<br>
> +++ llvm/trunk/lib/Fuzzer/<wbr>FuzzerClangCounters.cpp Fri Aug 11 16:03:22 2017<br>
> @@ -0,0 +1,49 @@<br>
> +//===- FuzzerExtraCounters.cpp - Extra coverage counters ------------------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +// Coverage counters from Clang's SourceBasedCodeCoverage.<br>
> +//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
> +<br>
> +// Support for SourceBasedCodeCoverage is experimental:<br>
> +// * Works only for the main binary, not DSOs yet.<br>
> +// * Works only on Linux.<br>
> +// * Does not implement print_pcs/print_coverage yet.<br>
> +// * Is not fully evaluated for performance and sensitivity.<br>
> +//   We expect large performance drop due to 64-bit counters,<br>
> +//   and *maybe* better sensitivity due to more fine-grained counters.<br>
> +//   Preliminary comparison on a single benchmark (RE2) shows<br>
> +//   a bit worse sensitivity though.<br>
> +<br>
> +#include "FuzzerDefs.h"<br>
> +<br>
> +#if LIBFUZZER_LINUX<br>
> +__attribute__((weak)) extern uint64_t __start___llvm_prf_cnts;<br>
> +__attribute__((weak)) extern uint64_t __stop___llvm_prf_cnts;<br>
> +namespace fuzzer {<br>
> +uint64_t *ClangCountersBegin() { return &__start___llvm_prf_cnts; }<br>
> +uint64_t *ClangCountersEnd() { return &__stop___llvm_prf_cnts; }<br>
> +}  // namespace fuzzer<br>
> +#else<br>
> +// TODO: Implement on Mac (if the data shows it's worth it).<br>
> +//__attribute__((visibility("<wbr>hidden")))<br>
> +//extern uint64_t CountersStart __asm("section$start$__DATA$__<wbr>llvm_prf_cnts");<br>
> +//__attribute__((visibility("<wbr>hidden")))<br>
> +//extern uint64_t CountersEnd __asm("section$end$__DATA$__<wbr>llvm_prf_cnts");<br>
> +namespace fuzzer {<br>
> +uint64_t *ClangCountersBegin() { return nullptr; }<br>
<br>
</div></div>Use: uint64_t *__llvm_profile_begin_<wbr>counters(void), and *_end_counters()?<br>
<span class="gmail-"><br>
> +uint64_t *ClangCountersEnd() { return  nullptr; }<br>
> +}  // namespace fuzzer<br>
> +#endif<br>
> +<br>
> +namespace fuzzer {<br>
> +ATTRIBUTE_NO_SANITIZE_ALL<br>
> +void ClearClangCounters() {  // hand-written memset, don't asan-ify.<br>
> +  for (auto P = ClangCountersBegin(); P < ClangCountersEnd(); P++)<br>
> +    *P = 0;<br>
> +}<br>
<br>
</span>Use: void __llvm_profile_reset_counters(<wbr>void); ?<br>
<div><div class="gmail-h5"><br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/Fuzzer/<wbr>FuzzerDefs.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDefs.h?rev=310771&r1=310770&r2=310771&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>FuzzerDefs.h?rev=310771&r1=<wbr>310770&r2=310771&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/<wbr>FuzzerDefs.h (original)<br>
> +++ llvm/trunk/lib/Fuzzer/<wbr>FuzzerDefs.h Fri Aug 11 16:03:22 2017<br>
> @@ -123,6 +123,10 @@ uint8_t *ExtraCountersBegin();<br>
> uint8_t *ExtraCountersEnd();<br>
> void ClearExtraCounters();<br>
><br>
> +uint64_t *ClangCountersBegin();<br>
> +uint64_t *ClangCountersEnd();<br>
> +void ClearClangCounters();<br>
> +<br>
> }  // namespace fuzzer<br>
><br>
> #endif  // LLVM_FUZZER_DEFS_H<br>
><br>
> Modified: llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=310771&r1=310770&r2=310771&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.cpp?rev=310771&<wbr>r1=310770&r2=310771&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.cpp (original)<br>
> +++ llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.cpp Fri Aug 11 16:03:22 2017<br>
> @@ -126,6 +126,8 @@ void TracePC::PrintModuleInfo() {<br>
>       _Exit(1);<br>
>     }<br>
>   }<br>
> +  if (size_t NumClangCounters = ClangCountersEnd() - ClangCountersBegin())<br>
> +    Printf("INFO: %zd Clang Coverage Counters\n", NumClangCounters);<br>
> }<br>
><br>
> ATTRIBUTE_NO_SANITIZE_ALL<br>
> @@ -137,13 +139,12 @@ void TracePC::HandleCallerCallee(<wbr>uintptr<br>
> }<br>
><br>
> void TracePC::UpdateObservedPCs() {<br>
<br>
</div></div>I'm a bit confused by what this is doing. Why is it interesting to track the indices of covered counters? </blockquote><div><br></div><div>This is just for printing statistics: how many different PCs are covered in total during the run. </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Isn't this something the recorded profile can tell you?<br></blockquote><div><br></div><div>What's "recorded profile"? </div><div>Given that I flush the array of counters after every input, there is no "recorded profile". </div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
best,<br>
vedant<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
> +  auto Observe = [&](uintptr_t PC) {<br>
> +    bool Inserted = ObservedPCs.insert(PC).second;<br>
> +    if (Inserted && DoPrintNewPCs)<br>
> +      PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);<br>
> +  };<br>
>   if (NumPCsInPCTables) {<br>
> -    auto Observe = [&](uintptr_t PC) {<br>
> -      bool Inserted = ObservedPCs.insert(PC).second;<br>
> -      if (Inserted && DoPrintNewPCs)<br>
> -        PrintPC("\tNEW_PC: %p %F %L\n", "\tNEW_PC: %p\n", PC + 1);<br>
> -    };<br>
> -<br>
>     if (NumInline8bitCounters == NumPCsInPCTables) {<br>
>       for (size_t i = 0; i < NumModulesWithInline8bitCounte<wbr>rs; i++) {<br>
>         uint8_t *Beg = ModuleCounters[i].Start;<br>
> @@ -167,6 +168,13 @@ void TracePC::UpdateObservedPCs() {<br>
>       }<br>
>     }<br>
>   }<br>
> +  if (size_t NumClangCounters =<br>
> +      ClangCountersEnd() - ClangCountersBegin()) {<br>
> +    auto P = ClangCountersBegin();<br>
> +    for (size_t Idx = 0; Idx < NumClangCounters; Idx++)<br>
> +      if (P[Idx])<br>
> +        Observe((uintptr_t)Idx);<br>
> +  }<br>
> }<br>
><br>
> inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(<wbr>uintptr_t PC) {<br>
><br>
> Modified: llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.h?rev=310771&r1=310770&r2=310771&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.h?rev=310771&r1=<wbr>310770&r2=310771&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.h (original)<br>
> +++ llvm/trunk/lib/Fuzzer/<wbr>FuzzerTracePC.h Fri Aug 11 16:03:22 2017<br>
> @@ -91,6 +91,7 @@ class TracePC {<br>
>       memset(Counters(), 0, GetNumPCs());<br>
>     ClearExtraCounters();<br>
>     ClearInlineCounters();<br>
> +    ClearClangCounters();<br>
>   }<br>
><br>
>   void ClearInlineCounters();<br>
> @@ -196,14 +197,9 @@ void ForEachNonZeroByte(const uint8_t *B<br>
>       Handle8bitCounter(<wbr>FirstFeature, P - Begin, V);<br>
> }<br>
><br>
> -template <class Callback>  // bool Callback(size_t Feature)<br>
> -ATTRIBUTE_NO_SANITIZE_ADDRESS<br>
> -__attribute__((noinline))<br>
> -void TracePC::CollectFeatures(<wbr>Callback HandleFeature) const {<br>
> -  uint8_t *Counters = this->Counters();<br>
> -  size_t N = GetNumPCs();<br>
> -  auto Handle8bitCounter = [&](size_t FirstFeature,<br>
> -                               size_t Idx, uint8_t Counter) {<br>
> +// Given a non-zero Counters returns a number in [0,7].<br>
> +template<class T><br>
> +unsigned CounterToFeature(T Counter) {<br>
>     assert(Counter);<br>
>     unsigned Bit = 0;<br>
>     /**/ if (Counter >= 128) Bit = 7;<br>
> @@ -213,7 +209,18 @@ void TracePC::CollectFeatures(<wbr>Callback H<br>
>     else if (Counter >= 4) Bit = 3;<br>
>     else if (Counter >= 3) Bit = 2;<br>
>     else if (Counter >= 2) Bit = 1;<br>
> -    HandleFeature(FirstFeature + Idx * 8 + Bit);<br>
> +    return Bit;<br>
> +}<br>
> +<br>
> +template <class Callback>  // bool Callback(size_t Feature)<br>
> +ATTRIBUTE_NO_SANITIZE_ADDRESS<br>
> +__attribute__((noinline))<br>
> +void TracePC::CollectFeatures(<wbr>Callback HandleFeature) const {<br>
> +  uint8_t *Counters = this->Counters();<br>
> +  size_t N = GetNumPCs();<br>
> +  auto Handle8bitCounter = [&](size_t FirstFeature,<br>
> +                               size_t Idx, uint8_t Counter) {<br>
> +    HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Counter));<br>
>   };<br>
><br>
>   size_t FirstFeature = 0;<br>
> @@ -231,6 +238,14 @@ void TracePC::CollectFeatures(<wbr>Callback H<br>
>     }<br>
>   }<br>
><br>
> +  if (size_t NumClangCounters = ClangCountersEnd() - ClangCountersBegin()) {<br>
> +    auto P = ClangCountersBegin();<br>
> +    for (size_t Idx = 0; Idx < NumClangCounters; Idx++)<br>
> +      if (auto Cnt = P[Idx])<br>
> +        HandleFeature(FirstFeature + Idx * 8 + CounterToFeature(Cnt));<br>
> +    FirstFeature += NumClangCounters;<br>
> +  }<br>
> +<br>
>   ForEachNonZeroByte(<wbr>ExtraCountersBegin(), ExtraCountersEnd(), FirstFeature,<br>
>                      Handle8bitCounter);<br>
>   FirstFeature += (ExtraCountersEnd() - ExtraCountersBegin()) * 8;<br>
><br>
> Added: llvm/trunk/lib/Fuzzer/test/<wbr>fprofile-instr-generate.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fprofile-instr-generate.test?rev=310771&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Fuzzer/<wbr>test/fprofile-instr-generate.<wbr>test?rev=310771&view=auto</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- llvm/trunk/lib/Fuzzer/test/<wbr>fprofile-instr-generate.test (added)<br>
> +++ llvm/trunk/lib/Fuzzer/test/<wbr>fprofile-instr-generate.test Fri Aug 11 16:03:22 2017<br>
> @@ -0,0 +1,7 @@<br>
> +# Test libFuzzer + -fprofile-instr-generate<br>
> +REQUIRES: linux<br>
> +RUN: %cpp_compiler %S/SimpleTest.cpp -fsanitize-coverage=0 -fprofile-instr-generate -o %t-SimpleTest-fprofile-instr-<wbr>generate<br>
> +CHECK-NOT: INFO: Loaded 1 modules<br>
> +CHECK: INFO: {{.*}} Clang Coverage Counters<br>
> +CHECK: BINGO<br>
> +RUN: not %t-SimpleTest-fprofile-instr-<wbr>generate -runs=1000000 -seed=1 2>&1 | FileCheck %s<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
<br>
</div></div></blockquote></div><br></div></div>