[llvm-branch-commits] [compiler-rt-branch] r276114 - Merging r275946 and r275948:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 20 06:43:47 PDT 2016


Author: hans
Date: Wed Jul 20 08:43:47 2016
New Revision: 276114

URL: http://llvm.org/viewvc/llvm-project?rev=276114&view=rev
Log:
Merging r275946 and r275948:

------------------------------------------------------------------------
r275946 | bruening | 2016-07-18 22:03:38 -0700 (Mon, 18 Jul 2016) | 5 lines

[esan] Fix sideline thread flaky assert

Fixes an esan sideline thread CHECK that failed to account for the sideline
thread reaching its code before the internal_clone() return value was
assigned in the parent.
------------------------------------------------------------------------

------------------------------------------------------------------------
r275948 | bruening | 2016-07-18 22:06:48 -0700 (Mon, 18 Jul 2016) | 4 lines

[esan|wset] Fix flaky sampling tests

Adds a new esan public interface routine __esan_get_sample_count() and uses
it to ensure that tests of sampling receive the minimum number of samples.
------------------------------------------------------------------------

Modified:
    compiler-rt/branches/release_39/   (props changed)
    compiler-rt/branches/release_39/include/sanitizer/esan_interface.h
    compiler-rt/branches/release_39/lib/esan/esan.cpp
    compiler-rt/branches/release_39/lib/esan/esan.h
    compiler-rt/branches/release_39/lib/esan/esan_interface.cpp
    compiler-rt/branches/release_39/lib/esan/esan_sideline_linux.cpp
    compiler-rt/branches/release_39/lib/esan/working_set.cpp
    compiler-rt/branches/release_39/lib/esan/working_set.h
    compiler-rt/branches/release_39/test/esan/TestCases/workingset-midreport.cpp
    compiler-rt/branches/release_39/test/esan/TestCases/workingset-samples.cpp

Propchange: compiler-rt/branches/release_39/
------------------------------------------------------------------------------
    svn:mergeinfo = /compiler-rt/trunk:275946,275948

Modified: compiler-rt/branches/release_39/include/sanitizer/esan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/include/sanitizer/esan_interface.h?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/include/sanitizer/esan_interface.h (original)
+++ compiler-rt/branches/release_39/include/sanitizer/esan_interface.h Wed Jul 20 08:43:47 2016
@@ -39,6 +39,10 @@ extern "C" {
 // data for that point in the run be reported from the tool.
 void COMPILER_RT_WEAK __esan_report();
 
+// This function returns the number of samples that the esan tool has collected
+// to this point.  This is useful for testing.
+unsigned int COMPILER_RT_WEAK __esan_get_sample_count();
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

Modified: compiler-rt/branches/release_39/lib/esan/esan.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/esan.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/esan.cpp (original)
+++ compiler-rt/branches/release_39/lib/esan/esan.cpp Wed Jul 20 08:43:47 2016
@@ -259,4 +259,12 @@ void processCompilationUnitExit(void *Pt
   }
 }
 
+unsigned int getSampleCount() {
+  VPrintf(1, "in esan::%s\n", __FUNCTION__);
+  if (__esan_which_tool == ESAN_WorkingSet) {
+    return getSampleCountWorkingSet();
+  }
+  return 0;
+}
+
 } // namespace __esan

Modified: compiler-rt/branches/release_39/lib/esan/esan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/esan.h?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/esan.h (original)
+++ compiler-rt/branches/release_39/lib/esan/esan.h Wed Jul 20 08:43:47 2016
@@ -38,6 +38,7 @@ extern bool EsanDuringInit;
 void initializeLibrary(ToolType Tool);
 int finalizeLibrary();
 void reportResults();
+unsigned int getSampleCount();
 // Esan creates the variable per tool per compilation unit at compile time
 // and passes its pointer Ptr to the runtime library.
 void processCompilationUnitInit(void *Ptr);

Modified: compiler-rt/branches/release_39/lib/esan/esan_interface.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/esan_interface.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/esan_interface.cpp (original)
+++ compiler-rt/branches/release_39/lib/esan/esan_interface.cpp Wed Jul 20 08:43:47 2016
@@ -115,4 +115,8 @@ extern "C" {
 SANITIZER_INTERFACE_ATTRIBUTE void __esan_report() {
   reportResults();
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE unsigned int __esan_get_sample_count() {
+  return getSampleCount();
+}
 } // extern "C"

Modified: compiler-rt/branches/release_39/lib/esan/esan_sideline_linux.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/esan_sideline_linux.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/esan_sideline_linux.cpp (original)
+++ compiler-rt/branches/release_39/lib/esan/esan_sideline_linux.cpp Wed Jul 20 08:43:47 2016
@@ -31,6 +31,7 @@ namespace __esan {
 
 static const int SigAltStackSize = 4*1024;
 static const int SidelineStackSize = 4*1024;
+static const uptr SidelineIdUninitialized = 1;
 
 // FIXME: we'll need some kind of TLS (can we trust that a pthread key will
 // work in our non-POSIX thread?) to access our data in our signal handler
@@ -113,6 +114,10 @@ bool SidelineThread::launchThread(Sideli
 
   // We do without a guard page.
   Stack = static_cast<char*>(MmapOrDie(SidelineStackSize, "SidelineStack"));
+  // We need to handle the return value from internal_clone() not having been
+  // assigned yet (for our CHECK in adjustTimer()) so we ensure this has a
+  // sentinel value.
+  SidelineId = SidelineIdUninitialized;
   // By omitting CLONE_THREAD, the child is in its own thread group and will not
   // receive any of the application's signals.
   SidelineId = internal_clone(
@@ -151,7 +156,9 @@ bool SidelineThread::joinThread() {
 
 // Must be called from the sideline thread itself.
 bool SidelineThread::adjustTimer(u32 FreqMilliSec) {
-  CHECK(internal_getpid() == SidelineId);
+  // The return value of internal_clone() may not have been assigned yet:
+  CHECK(internal_getpid() == SidelineId ||
+        SidelineId == SidelineIdUninitialized);
   Freq = FreqMilliSec;
   struct itimerval TimerVal;
   TimerVal.it_interval.tv_sec = (time_t) Freq / 1000;

Modified: compiler-rt/branches/release_39/lib/esan/working_set.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/working_set.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/working_set.cpp (original)
+++ compiler-rt/branches/release_39/lib/esan/working_set.cpp Wed Jul 20 08:43:47 2016
@@ -190,6 +190,11 @@ static void takeSample(void *Arg) {
   }
 }
 
+unsigned int getSampleCountWorkingSet()
+{
+  return SnapshotNum;
+}
+
 // Initialization that must be done before any instrumented code is executed.
 void initializeShadowWorkingSet() {
   CHECK(getFlags()->cache_line_size == CacheLineSize);

Modified: compiler-rt/branches/release_39/lib/esan/working_set.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/lib/esan/working_set.h?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/lib/esan/working_set.h (original)
+++ compiler-rt/branches/release_39/lib/esan/working_set.h Wed Jul 20 08:43:47 2016
@@ -24,6 +24,7 @@ void initializeWorkingSet();
 void initializeShadowWorkingSet();
 int finalizeWorkingSet();
 void reportWorkingSet();
+unsigned int getSampleCountWorkingSet();
 void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
                                   bool IsWrite);
 

Modified: compiler-rt/branches/release_39/test/esan/TestCases/workingset-midreport.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/test/esan/TestCases/workingset-midreport.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/test/esan/TestCases/workingset-midreport.cpp (original)
+++ compiler-rt/branches/release_39/test/esan/TestCases/workingset-midreport.cpp Wed Jul 20 08:43:47 2016
@@ -17,15 +17,15 @@ const int iters = 6;
 int main(int argc, char **argv) {
   char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-  // Try to increase the probability that the sideline thread is
-  // scheduled.  Unfortunately we can't do proper synchronization
-  // without some form of annotation or something.
-  sched_yield();
-  // Do enough work to get at least 4 samples.
-  for (int j = 0; j < iters; ++j) {
-    for (int i = 0; i < size; ++i)
-      buf[i] = i;
-    sched_yield();
+  // To avoid flakiness stemming from whether the sideline thread
+  // is scheduled enough on a loaded test machine, we coordinate
+  // with esan itself:
+  if (__esan_get_sample_count) {
+    while (__esan_get_sample_count() < 4) {
+      for (int i = 0; i < size; ++i)
+        buf[i] = i;
+      sched_yield();
+    }
   }
   // Ensure a non-esan build works without ifdefs:
   if (__esan_report) {

Modified: compiler-rt/branches/release_39/test/esan/TestCases/workingset-samples.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/branches/release_39/test/esan/TestCases/workingset-samples.cpp?rev=276114&r1=276113&r2=276114&view=diff
==============================================================================
--- compiler-rt/branches/release_39/test/esan/TestCases/workingset-samples.cpp (original)
+++ compiler-rt/branches/release_39/test/esan/TestCases/workingset-samples.cpp Wed Jul 20 08:43:47 2016
@@ -1,6 +1,7 @@
 // RUN: %clang_esan_wset -O0 %s -o %t 2>&1
 // RUN: %run %t 2>&1 | FileCheck %s
 
+#include <sanitizer/esan_interface.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <string.h>
@@ -12,15 +13,15 @@ const int iters = 6;
 int main(int argc, char **argv) {
   char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-  // Try to increase the probability that the sideline thread is
-  // scheduled.  Unfortunately we can't do proper synchronization
-  // without some form of annotation or something.
-  sched_yield();
-  // Do enough work to get at least 4 samples.
-  for (int j = 0; j < iters; ++j) {
-    for (int i = 0; i < size; ++i)
-      buf[i] = i;
-    sched_yield();
+  // To avoid flakiness stemming from whether the sideline thread
+  // is scheduled enough on a loaded test machine, we coordinate
+  // with esan itself:
+  if (__esan_get_sample_count) {
+    while (__esan_get_sample_count() < 4) {
+      for (int i = 0; i < size; ++i)
+        buf[i] = i;
+      sched_yield();
+    }
   }
   munmap(buf, size);
   // We only check for a few samples here to reduce the chance of flakiness.




More information about the llvm-branch-commits mailing list