summaryrefslogtreecommitdiff
path: root/lib/esan
diff options
context:
space:
mode:
authorDerek Bruening <bruening@google.com>2016-07-19 05:03:38 +0000
committerDerek Bruening <bruening@google.com>2016-07-19 05:03:38 +0000
commit189001e3bc9f050781628eba7da36f90725b04ba (patch)
treeff91b81cbdb197071c583a2dc14ba9e169e6a5c2 /lib/esan
parentf609165826c7e7141385967fd3e9dcc29b65a18b (diff)
[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. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@275946 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/esan')
-rw-r--r--lib/esan/esan_sideline_linux.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/lib/esan/esan_sideline_linux.cpp b/lib/esan/esan_sideline_linux.cpp
index ba4fe62f5..d04f5909d 100644
--- a/lib/esan/esan_sideline_linux.cpp
+++ b/lib/esan/esan_sideline_linux.cpp
@@ -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(SidelineFunc takeSample, void *Arg,
// 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;