<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 4, 2015 at 4:50 PM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Wed, Mar 4, 2015 at 3:41 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: kcc<br>
Date: Wed Mar  4 17:41:55 2015<br>
New Revision: 231319<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=231319&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=231319&view=rev</a><br>
Log:<br>
[sanitizer] when dumping coverage bitset, dump seperate file for every module, instead of dumping a single combined bitset<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h<br>
    compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=231319&r1=231318&r2=231319&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=231319&r1=231318&r2=231319&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Mar  4 17:41:55 2015<br>
@@ -450,6 +450,7 @@ class InternalMmapVectorNoCtor {<br>
   }<br>
<br>
   void clear() { size_ = 0; }<br>
+  bool empty() const { return size() == 0; }<br>
<br>
  private:<br>
   void Resize(uptr new_capacity) {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=231319&r1=231318&r2=231319&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=231319&r1=231318&r2=231319&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Wed Mar  4 17:41:55 2015<br>
@@ -77,12 +77,15 @@ class CoverageData {<br>
                  uptr cache_size);<br>
   void DumpCallerCalleePairs();<br>
   void DumpTrace();<br>
+  void DumpAsBitSet();<br>
<br>
   ALWAYS_INLINE<br>
   void TraceBasicBlock(s32 *id);<br>
<br>
   void InitializeGuardArray(s32 *guards);<br>
-  void InitializeGuards(s32 *guards, uptr n, const char *module_name);<br>
+  void InitializeGuards(s32 *guards, uptr n, const char *module_name,<br>
+                        uptr caller_pc);<br>
+  void UpdateModuleNameVec(uptr caller_pc, uptr range_beg, uptr range_end);<br>
   void InitializeCounters(u8 *counters, uptr n);<br>
   void ReinitializeGuards();<br>
   uptr GetNumberOf8bitCounters();<br>
@@ -113,8 +116,14 @@ class CoverageData {<br>
   // Vector of coverage guard arrays, protected by mu.<br>
   InternalMmapVectorNoCtor<s32*> guard_array_vec;<br>
<br>
-  // Vector of module (compilation unit) names.<br>
-  InternalMmapVectorNoCtor<const char*> comp_unit_name_vec;<br>
+  struct NamedPcRange {<br>
+    const char *name;<br>
+    uptr beg, end; // elements [beg,end) in pc_array.<br>
+  };<br>
+<br>
+  // Vector of module and compilation unit pc ranges.<br>
+  InternalMmapVectorNoCtor<NamedPcRange> comp_unit_name_vec;<br>
+  InternalMmapVectorNoCtor<NamedPcRange> module_name_vec;<br>
<br>
   struct CounterAndSize {<br>
     u8 *counters;<br>
@@ -311,16 +320,33 @@ void CoverageData::InitializeCounters(u8<br>
   num_8bit_counters += n;<br>
 }<br>
<br>
+void CoverageData::UpdateModuleNameVec(uptr caller_pc, uptr range_beg,<br>
+                                       uptr range_end) {<br>
+  auto sym = Symbolizer::GetOrInit();<br>
+  if (!sym)<br>
+    return;<br>
+  const char *module_name = sym->GetModuleNameForPc(caller_pc);<br>
+  if (!module_name) return;<br>
+  if (module_name_vec.empty() || module_name_vec.back().name != module_name)<br>
+    module_name_vec.push_back({module_name, range_beg, range_end});<br>
+  else<br>
+    module_name_vec.back().end = range_end;<br>
+}<br>
+<br>
 void CoverageData::InitializeGuards(s32 *guards, uptr n,<br>
-                                    const char *module_name) {<br>
+                                    const char *comp_unit_name,<br>
+                                    uptr caller_pc) {<br>
   // The array 'guards' has n+1 elements, we use the element zero<br>
   // to store 'n'.<br>
   CHECK_LT(n, 1 << 30);<br>
   guards[0] = static_cast<s32>(n);<br>
   InitializeGuardArray(guards);<br>
   SpinMutexLock l(&mu);<br>
-  comp_unit_name_vec.push_back(module_name);<br>
+  uptr range_end = atomic_load(&pc_array_index, memory_order_relaxed);<br>
+  uptr range_beg = range_end - n;<br>
+  comp_unit_name_vec.push_back({comp_unit_name, range_beg, range_end});<br>
   guard_array_vec.push_back(guards);<br>
+  UpdateModuleNameVec(caller_pc, range_beg, range_end);<br>
 }<br>
<br>
 // If guard is negative, atomically set it to -guard and store the PC in<br>
@@ -539,7 +565,7 @@ void CoverageData::DumpTrace() {<br>
   if (fd < 0) return;<br>
   out.clear();<br>
   for (uptr i = 0; i < comp_unit_name_vec.size(); i++)<br>
-    out.append("%s\n", comp_unit_name_vec[i]);<br>
+    out.append("%s\n", comp_unit_name_vec[i].name);<br>
   internal_write(fd, out.data(), out.length());<br>
   internal_close(fd);<br>
<br>
@@ -614,24 +640,31 @@ void CoverageData::TraceBasicBlock(s32 *<br>
   tr_event_pointer++;<br>
 }<br>
<br>
-static void CovDumpAsBitSet() {<br>
+void CoverageData::DumpAsBitSet() {<br>
   if (!common_flags()->coverage_bitset) return;<br>
-  if (!coverage_data.size()) return;<br>
-  int fd = CovOpenFile(/* packed */false, "combined", "bitset-sancov");<br>
-  if (fd < 0) return;<br>
-  uptr n = coverage_data.size();<br>
-  uptr n_set_bits = 0;<br>
-  InternalScopedBuffer<char> out(n);<br>
-  for (uptr i = 0; i < n; i++) {<br>
-    uptr pc = coverage_data.data()[i];<br>
-    out[i] = pc ? '1' : '0';<br>
-    if (pc)<br>
-      n_set_bits++;<br>
+  if (!size()) return;<br>
+  InternalScopedBuffer<char> out(size());<br>
+  for (uptr m = 0; m < module_name_vec.size(); m++) {<br>
+    uptr n_set_bits = 0;<br>
+    auto r = module_name_vec[m];<br>
+    CHECK(<a href="http://r.name" target="_blank">r.name</a>);<br>
+    CHECK_LE(r.beg, r.end);<br>
+    CHECK_LE(r.end, size());<br>
+    for (uptr i = r.beg; i < r.end; i++) {<br>
+      uptr pc = data()[i];<br>
+      out[i] = pc ? '1' : '0';<br>
+      if (pc)<br>
+        n_set_bits++;<br>
+    }<br>
+    const char *base_name = StripModuleName(<a href="http://r.name" target="_blank">r.name</a>);<br>
+    int fd = CovOpenFile(/* packed */ false, base_name, "bitset-sancov");<br>
+    if (fd < 0) return;<br>
+    internal_write(fd, out.data() + r.beg, r.end - r.beg);<br>
+    internal_close(fd);<br>
+    VReport(1,<br>
+            " CovDump: bitset of %zd bits written for '%s', %zd bits are set\n",<br>
+            r.end - r.beg, base_name, n_set_bits);<br>
   }<br>
-  internal_write(fd, out.data(), n);<br>
-  internal_close(fd);<br>
-  VReport(1, " CovDump: bitset of %zd bits written, %zd bits are set\n", n,<br>
-          n_set_bits);<br>
 }<br>
<br>
 // Dump the coverage on disk.<br>
@@ -640,7 +673,7 @@ static void CovDump() {<br>
 #if !SANITIZER_WINDOWS<br>
   if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))<br>
     return;<br>
-  CovDumpAsBitSet();<br>
+  coverage_data.DumpAsBitSet();<br>
   coverage_data.DumpTrace();<br>
   if (!common_flags()->coverage_pcs) return;<br>
   uptr size = coverage_data.size();<br>
@@ -770,8 +803,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __san<br>
 SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); }<br>
 SANITIZER_INTERFACE_ATTRIBUTE void<br>
 __sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,<br>
-                            const char *module_name) {<br>
-  coverage_data.InitializeGuards(guards, npcs, module_name);<br>
+                            const char *comp_unit_name) {<br>
+  coverage_data.InitializeGuards(guards, npcs, comp_unit_name, GET_CALLER_PC());<br>
   coverage_data.InitializeCounters(counters, npcs);<br>
   if (!common_flags()->coverage_direct) return;<br>
   if (SANITIZER_ANDROID && coverage_enabled) {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=231319&r1=231318&r2=231319&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=231319&r1=231318&r2=231319&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Wed Mar  4 17:41:55 2015<br>
@@ -90,6 +90,13 @@ class Symbolizer {<br>
                                            uptr *module_address) {<br>
     return false;<br>
   }<br>
+  const char *GetModuleNameForPc(uptr pc) {<br>
+    const char *module_name = 0;<br>
+    uptr unused;<br>
+    if (GetModuleNameAndOffsetForPC(pc, &module_name, &unused))<br>
+      return module_name;<br>
+    return nullptr;<br>
+  }<br></blockquote><div><br></div></div></div><div>^^</div><div>Please either use GetModuleNameAndOffsetForPC(pc, module_name, &unused) at call site</div><div>(to keep the Symbolizer interface simple), or, if you think that introducing new function is important</div><div>for making the code more concise, migrate the existing users that don't care about offset_pc (ASan and LSan suppression code).</div></div></div></div></blockquote><div><br></div><div>Agree with the latter, r231337. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
   virtual bool CanReturnFileLineInfo() {<br>
     return false;<br>
   }<br>
<br>
Modified: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc?rev=231319&r1=231318&r2=231319&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc?rev=231319&r1=231318&r2=231319&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc (original)<br>
+++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-levels.cc Wed Mar  4 17:41:55 2015<br>
@@ -19,11 +19,11 @@ int main(int argc, char **argv) {<br>
     sink = 0;<br>
 }<br>
<br>
-// CHECK1: CovDump: bitset of 1 bits written, 1 bits are set<br>
+// CHECK1: CovDump: bitset of 1 bits written for '{{.*}}', 1 bits are set<br>
 // CHECK1:  1 PCs written<br>
-// CHECK2: CovDump: bitset of 3 bits written, 2 bits are set<br>
+// CHECK2: CovDump: bitset of 3 bits written for '{{.*}}', 2 bits are set<br>
 // CHECK2:  2 PCs written<br>
-// CHECK3: CovDump: bitset of 4 bits written, 3 bits are set<br>
+// CHECK3: CovDump: bitset of 4 bits written for '{{.*}}', 3 bits are set<br>
 // CHECK3:  3 PCs written<br>
 // CHECK3_NOBITSET-NOT: bitset of<br>
 // CHECK3_NOPCS-NOT: PCs written<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></span></div><span class=""><font color="#888888"><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</font></span></div></div>
</blockquote></div><br></div></div>