Commit e3b140ea authored by eroman@chromium.org's avatar eroman@chromium.org

Temporary instrumentation to help understand lock errors on mac debug bots.

BUG=102161

Review URL: http://codereview.chromium.org/8414031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107835 0039d316-1c4b-4281-b951-d872f2087c98
parent 5875dd0f
...@@ -17,6 +17,18 @@ ...@@ -17,6 +17,18 @@
#include "base/base_export.h" #include "base/base_export.h"
#include "base/basictypes.h" #include "base/basictypes.h"
#if defined(OS_MACOSX) && !defined(NDEBUG)
// For Mac debug builds, do some extra checks to make sure a LockImpl is not
// used after it has been freed. This instrumentation is to help track down
// spurious locking errors (EINVAL) which are happening on the bots.
// In particular, I want to make sure they aren't a consequence of having
// used a freed lock object (which can happen for instance when trying to
// post tasks to a destroyed MessageLoop).
// See http://crbug.com/102161 for more details. This instrumentation can be
// removed once that bug has been identified.
#define LOCK_IMPL_CHECK_LIVENESS
#endif
namespace base { namespace base {
namespace internal { namespace internal {
...@@ -53,6 +65,17 @@ class BASE_EXPORT LockImpl { ...@@ -53,6 +65,17 @@ class BASE_EXPORT LockImpl {
#endif #endif
private: private:
#ifdef LOCK_IMPL_CHECK_LIVENESS
enum LivenessToken {
LT_ALIVE = 0xCa11ab1e, // 3390155550
LT_DELETED = 0xDecea5ed, // 3738084845
};
void CheckIsAlive();
LivenessToken liveness_token_;
#endif // LOCK_IMPL_CHECK_LIVENESS
OSLockType os_lock_; OSLockType os_lock_;
DISALLOW_COPY_AND_ASSIGN(LockImpl); DISALLOW_COPY_AND_ASSIGN(LockImpl);
......
...@@ -12,6 +12,10 @@ namespace base { ...@@ -12,6 +12,10 @@ namespace base {
namespace internal { namespace internal {
LockImpl::LockImpl() { LockImpl::LockImpl() {
#ifdef LOCK_IMPL_CHECK_LIVENESS
liveness_token_ = LT_ALIVE;
#endif
#ifndef NDEBUG #ifndef NDEBUG
// In debug, setup attributes for lock error checking. // In debug, setup attributes for lock error checking.
pthread_mutexattr_t mta; pthread_mutexattr_t mta;
...@@ -30,25 +34,45 @@ LockImpl::LockImpl() { ...@@ -30,25 +34,45 @@ LockImpl::LockImpl() {
} }
LockImpl::~LockImpl() { LockImpl::~LockImpl() {
#ifdef LOCK_IMPL_CHECK_LIVENESS
CheckIsAlive();
liveness_token_ = LT_DELETED;
#endif
int rv = pthread_mutex_destroy(&os_lock_); int rv = pthread_mutex_destroy(&os_lock_);
DCHECK_EQ(rv, 0); DCHECK_EQ(rv, 0);
} }
bool LockImpl::Try() { bool LockImpl::Try() {
#ifdef LOCK_IMPL_CHECK_LIVENESS
CheckIsAlive();
#endif
int rv = pthread_mutex_trylock(&os_lock_); int rv = pthread_mutex_trylock(&os_lock_);
DCHECK(rv == 0 || rv == EBUSY); DCHECK(rv == 0 || rv == EBUSY);
return rv == 0; return rv == 0;
} }
void LockImpl::Lock() { void LockImpl::Lock() {
#ifdef LOCK_IMPL_CHECK_LIVENESS
CheckIsAlive();
#endif
int rv = pthread_mutex_lock(&os_lock_); int rv = pthread_mutex_lock(&os_lock_);
DCHECK_EQ(rv, 0); DCHECK_EQ(rv, 0);
} }
void LockImpl::Unlock() { void LockImpl::Unlock() {
#ifdef LOCK_IMPL_CHECK_LIVENESS
CheckIsAlive();
#endif
int rv = pthread_mutex_unlock(&os_lock_); int rv = pthread_mutex_unlock(&os_lock_);
DCHECK_EQ(rv, 0); DCHECK_EQ(rv, 0);
} }
#ifdef LOCK_IMPL_CHECK_LIVENESS
void LockImpl::CheckIsAlive() {
CHECK_EQ(LT_ALIVE, liveness_token_)
<< "Lock was invalid. Please see: http://crbug.com/102161";
}
#endif
} // namespace internal } // namespace internal
} // namespace base } // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment