[compiler-rt] r231319 - [sanitizer] when dumping coverage bitset, dump seperate file for every module, instead of dumping a single combined bitset

Alexey Samsonov vonosmas at gmail.com
Wed Mar 4 16:50:33 PST 2015


On Wed, Mar 4, 2015 at 3:41 PM, Kostya Serebryany <kcc at google.com> wrote:

> Author: kcc
> Date: Wed Mar  4 17:41:55 2015
> New Revision: 231319
>
> URL: http://llvm.org/viewvc/llvm-project?rev=231319&view=rev
> Log:
> [sanitizer] when dumping coverage bitset, dump seperate file for every
> module, instead of dumping a single combined bitset
>
> Modified:
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
>     compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=231319&r1=231318&r2=231319&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Mar  4
> 17:41:55 2015
> @@ -450,6 +450,7 @@ class InternalMmapVectorNoCtor {
>    }
>
>    void clear() { size_ = 0; }
> +  bool empty() const { return size() == 0; }
>
>   private:
>    void Resize(uptr new_capacity) {
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=231319&r1=231318&r2=231319&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> Wed Mar  4 17:41:55 2015
> @@ -77,12 +77,15 @@ class CoverageData {
>                   uptr cache_size);
>    void DumpCallerCalleePairs();
>    void DumpTrace();
> +  void DumpAsBitSet();
>
>    ALWAYS_INLINE
>    void TraceBasicBlock(s32 *id);
>
>    void InitializeGuardArray(s32 *guards);
> -  void InitializeGuards(s32 *guards, uptr n, const char *module_name);
> +  void InitializeGuards(s32 *guards, uptr n, const char *module_name,
> +                        uptr caller_pc);
> +  void UpdateModuleNameVec(uptr caller_pc, uptr range_beg, uptr
> range_end);
>    void InitializeCounters(u8 *counters, uptr n);
>    void ReinitializeGuards();
>    uptr GetNumberOf8bitCounters();
> @@ -113,8 +116,14 @@ class CoverageData {
>    // Vector of coverage guard arrays, protected by mu.
>    InternalMmapVectorNoCtor<s32*> guard_array_vec;
>
> -  // Vector of module (compilation unit) names.
> -  InternalMmapVectorNoCtor<const char*> comp_unit_name_vec;
> +  struct NamedPcRange {
> +    const char *name;
> +    uptr beg, end; // elements [beg,end) in pc_array.
> +  };
> +
> +  // Vector of module and compilation unit pc ranges.
> +  InternalMmapVectorNoCtor<NamedPcRange> comp_unit_name_vec;
> +  InternalMmapVectorNoCtor<NamedPcRange> module_name_vec;
>
>    struct CounterAndSize {
>      u8 *counters;
> @@ -311,16 +320,33 @@ void CoverageData::InitializeCounters(u8
>    num_8bit_counters += n;
>  }
>
> +void CoverageData::UpdateModuleNameVec(uptr caller_pc, uptr range_beg,
> +                                       uptr range_end) {
> +  auto sym = Symbolizer::GetOrInit();
> +  if (!sym)
> +    return;
> +  const char *module_name = sym->GetModuleNameForPc(caller_pc);
> +  if (!module_name) return;
> +  if (module_name_vec.empty() || module_name_vec.back().name !=
> module_name)
> +    module_name_vec.push_back({module_name, range_beg, range_end});
> +  else
> +    module_name_vec.back().end = range_end;
> +}
> +
>  void CoverageData::InitializeGuards(s32 *guards, uptr n,
> -                                    const char *module_name) {
> +                                    const char *comp_unit_name,
> +                                    uptr caller_pc) {
>    // The array 'guards' has n+1 elements, we use the element zero
>    // to store 'n'.
>    CHECK_LT(n, 1 << 30);
>    guards[0] = static_cast<s32>(n);
>    InitializeGuardArray(guards);
>    SpinMutexLock l(&mu);
> -  comp_unit_name_vec.push_back(module_name);
> +  uptr range_end = atomic_load(&pc_array_index, memory_order_relaxed);
> +  uptr range_beg = range_end - n;
> +  comp_unit_name_vec.push_back({comp_unit_name, range_beg, range_end});
>    guard_array_vec.push_back(guards);
> +  UpdateModuleNameVec(caller_pc, range_beg, range_end);
>  }
>
>  // If guard is negative, atomically set it to -guard and store the PC in
> @@ -539,7 +565,7 @@ void CoverageData::DumpTrace() {
>    if (fd < 0) return;
>    out.clear();
>    for (uptr i = 0; i < comp_unit_name_vec.size(); i++)
> -    out.append("%s\n", comp_unit_name_vec[i]);
> +    out.append("%s\n", comp_unit_name_vec[i].name);
>    internal_write(fd, out.data(), out.length());
>    internal_close(fd);
>
> @@ -614,24 +640,31 @@ void CoverageData::TraceBasicBlock(s32 *
>    tr_event_pointer++;
>  }
>
> -static void CovDumpAsBitSet() {
> +void CoverageData::DumpAsBitSet() {
>    if (!common_flags()->coverage_bitset) return;
> -  if (!coverage_data.size()) return;
> -  int fd = CovOpenFile(/* packed */false, "combined", "bitset-sancov");
> -  if (fd < 0) return;
> -  uptr n = coverage_data.size();
> -  uptr n_set_bits = 0;
> -  InternalScopedBuffer<char> out(n);
> -  for (uptr i = 0; i < n; i++) {
> -    uptr pc = coverage_data.data()[i];
> -    out[i] = pc ? '1' : '0';
> -    if (pc)
> -      n_set_bits++;
> +  if (!size()) return;
> +  InternalScopedBuffer<char> out(size());
> +  for (uptr m = 0; m < module_name_vec.size(); m++) {
> +    uptr n_set_bits = 0;
> +    auto r = module_name_vec[m];
> +    CHECK(r.name);
> +    CHECK_LE(r.beg, r.end);
> +    CHECK_LE(r.end, size());
> +    for (uptr i = r.beg; i < r.end; i++) {
> +      uptr pc = data()[i];
> +      out[i] = pc ? '1' : '0';
> +      if (pc)
> +        n_set_bits++;
> +    }
> +    const char *base_name = StripModuleName(r.name);
> +    int fd = CovOpenFile(/* packed */ false, base_name, "bitset-sancov");
> +    if (fd < 0) return;
> +    internal_write(fd, out.data() + r.beg, r.end - r.beg);
> +    internal_close(fd);
> +    VReport(1,
> +            " CovDump: bitset of %zd bits written for '%s', %zd bits are
> set\n",
> +            r.end - r.beg, base_name, n_set_bits);
>    }
> -  internal_write(fd, out.data(), n);
> -  internal_close(fd);
> -  VReport(1, " CovDump: bitset of %zd bits written, %zd bits are set\n",
> n,
> -          n_set_bits);
>  }
>
>  // Dump the coverage on disk.
> @@ -640,7 +673,7 @@ static void CovDump() {
>  #if !SANITIZER_WINDOWS
>    if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))
>      return;
> -  CovDumpAsBitSet();
> +  coverage_data.DumpAsBitSet();
>    coverage_data.DumpTrace();
>    if (!common_flags()->coverage_pcs) return;
>    uptr size = coverage_data.size();
> @@ -770,8 +803,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __san
>  SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); }
>  SANITIZER_INTERFACE_ATTRIBUTE void
>  __sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,
> -                            const char *module_name) {
> -  coverage_data.InitializeGuards(guards, npcs, module_name);
> +                            const char *comp_unit_name) {
> +  coverage_data.InitializeGuards(guards, npcs, comp_unit_name,
> GET_CALLER_PC());
>    coverage_data.InitializeCounters(counters, npcs);
>    if (!common_flags()->coverage_direct) return;
>    if (SANITIZER_ANDROID && coverage_enabled) {
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=231319&r1=231318&r2=231319&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Wed Mar
> 4 17:41:55 2015
> @@ -90,6 +90,13 @@ class Symbolizer {
>                                             uptr *module_address) {
>      return false;
>    }
> +  const char *GetModuleNameForPc(uptr pc) {
> +    const char *module_name = 0;
> +    uptr unused;
> +    if (GetModuleNameAndOffsetForPC(pc, &module_name, &unused))
> +      return module_name;
> +    return nullptr;
> +  }
>

^^
Please either use GetModuleNameAndOffsetForPC(pc, module_name, &unused) at
call site
(to keep the Symbolizer interface simple), or, if you think that
introducing new function is important
for making the code more concise, migrate the existing users that don't
care about offset_pc (ASan and LSan suppression code).



>    virtual bool CanReturnFileLineInfo() {
>      return false;
>    }
>
> Modified: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc?rev=231319&r1=231318&r2=231319&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc
> (original)
> +++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc Wed
> Mar  4 17:41:55 2015
> @@ -19,11 +19,11 @@ int main(int argc, char **argv) {
>      sink = 0;
>  }
>
> -// CHECK1: CovDump: bitset of 1 bits written, 1 bits are set
> +// CHECK1: CovDump: bitset of 1 bits written for '{{.*}}', 1 bits are set
>  // CHECK1:  1 PCs written
> -// CHECK2: CovDump: bitset of 3 bits written, 2 bits are set
> +// CHECK2: CovDump: bitset of 3 bits written for '{{.*}}', 2 bits are set
>  // CHECK2:  2 PCs written
> -// CHECK3: CovDump: bitset of 4 bits written, 3 bits are set
> +// CHECK3: CovDump: bitset of 4 bits written for '{{.*}}', 3 bits are set
>  // CHECK3:  3 PCs written
>  // CHECK3_NOBITSET-NOT: bitset of
>  // CHECK3_NOPCS-NOT: PCs written
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150304/0fc16c7d/attachment.html>


More information about the llvm-commits mailing list