Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc @@ -348,20 +348,16 @@ void BlockingMutex::Lock() { CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_)); CHECK_EQ(OS_SPINLOCK_INIT, 0); - CHECK_NE(owner_, (uptr)pthread_self()); + CHECK_EQ(owner_, 0); OSSpinLockLock((OSSpinLock*)&opaque_storage_); - CHECK(!owner_); - owner_ = (uptr)pthread_self(); } void BlockingMutex::Unlock() { - CHECK(owner_ == (uptr)pthread_self()); - owner_ = 0; OSSpinLockUnlock((OSSpinLock*)&opaque_storage_); } void BlockingMutex::CheckLocked() { - CHECK_EQ((uptr)pthread_self(), owner_); + CHECK_NE(*(OSSpinLock*)&opaque_storage_, 0); } u64 NanoTime() { Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h @@ -83,6 +83,14 @@ BlockingMutex(); void Lock(); void Unlock(); + + // This function does not guarantee an explicit check that the calling thread + // is the thread which owns the mutex. This behavior, while more strictly + // correct, causes problems in cases like StopTheWorld, where a parent thread + // owns the mutex but a child checks that it is locked. Rather than + // maintaining complex state to work around those situations, the check only + // checks that the mutex is owned, and assumes callers to be generally + // well-behaved. void CheckLocked(); private: uptr opaque_storage_[10];