[Lldb-commits] [lldb] r154637 - /lldb/trunk/source/Host/common/Mutex.cpp

Greg Clayton gclayton at apple.com
Thu Apr 12 17:21:53 PDT 2012


Author: gclayton
Date: Thu Apr 12 19:21:53 2012
New Revision: 154637

URL: http://llvm.org/viewvc/llvm-project?rev=154637&view=rev
Log:
Added more complete error checking for mutexes only for "Debug" builds where we always check if a mutex is valid prior to doing stuff with it. We also track when mutexes are initialized and destroyed and keep these in sets that can very subsequent pthread_mutex_XXX API calls.


Modified:
    lldb/trunk/source/Host/common/Mutex.cpp

Modified: lldb/trunk/source/Host/common/Mutex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Mutex.cpp?rev=154637&r1=154636&r2=154637&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Mutex.cpp (original)
+++ lldb/trunk/source/Host/common/Mutex.cpp Thu Apr 12 19:21:53 2012
@@ -29,6 +29,61 @@
 #define ENABLE_MUTEX_ERROR_CHECKING 1
 #endif
 
+#if ENABLE_MUTEX_ERROR_CHECKING
+#include <set>
+
+enum MutexAction
+{
+    eMutexActionInitialized,
+    eMutexActionDestroyed,
+    eMutexActionAssertInitialized
+};
+
+static bool
+error_check_mutex (pthread_mutex_t *m, MutexAction action)
+{
+    typedef std::set<pthread_mutex_t *> mutex_set;
+    static pthread_mutex_t g_mutex_set_mutex = PTHREAD_MUTEX_INITIALIZER;
+    mutex_set g_initialized_mutex_set;
+    mutex_set g_destroyed_mutex_set;
+
+    bool success = true;
+    int err;
+    // Manually call lock so we don't to any of this error checking
+    err = ::pthread_mutex_lock (&g_mutex_set_mutex);
+    assert(err == 0);
+    switch (action)
+    {
+        case eMutexActionInitialized:
+            // Make sure this isn't already in our initialized mutex set...
+            assert (g_initialized_mutex_set.find(m) == g_initialized_mutex_set.end());
+            // Remove this from the destroyed set in case it was ever in there
+            g_destroyed_mutex_set.erase(m);
+            // Add the mutex to the initialized set
+            g_initialized_mutex_set.insert(m);
+            break;
+            
+        case eMutexActionDestroyed:
+            // Make sure this isn't already in our destroyed mutex set...
+            assert (g_destroyed_mutex_set.find(m) == g_destroyed_mutex_set.end());
+            // Remove this from the initialized so we can put it into the destroyed set
+            g_initialized_mutex_set.erase(m);
+            // Add the mutex to the destroyed set
+            g_destroyed_mutex_set.insert(m);
+            break;
+        case eMutexActionAssertInitialized:
+            // This function will return true if "m" is in the initialized mutex set
+            success = g_initialized_mutex_set.find(m) != g_initialized_mutex_set.end();
+            break;
+    }
+    // Manually call unlock so we don't to any of this error checking
+    err = ::pthread_mutex_unlock (&g_mutex_set_mutex);
+    assert(err == 0);
+    return success;
+}
+
+#endif
+
 using namespace lldb_private;
 
 //----------------------------------------------------------------------
@@ -147,6 +202,10 @@
 {
     int err;
     err = ::pthread_mutex_init (&m_mutex, NULL);
+#if ENABLE_MUTEX_ERROR_CHECKING
+    if (err == 0)
+        error_check_mutex (&m_mutex, eMutexActionInitialized);
+#endif
     assert(err == 0);
 }
 
@@ -182,6 +241,10 @@
     }
     assert(err == 0);
     err = ::pthread_mutex_init (&m_mutex, &attr);
+#if ENABLE_MUTEX_ERROR_CHECKING
+    if (err == 0)
+        error_check_mutex (&m_mutex, eMutexActionInitialized);
+#endif
     assert(err == 0);
     err = ::pthread_mutexattr_destroy (&attr);
     assert(err == 0);
@@ -197,7 +260,9 @@
     int err;
     err = ::pthread_mutex_destroy (&m_mutex);
 #if ENABLE_MUTEX_ERROR_CHECKING
-    if (err)
+    if (err == 0)
+        error_check_mutex (&m_mutex, eMutexActionDestroyed);
+    else
     {
         Host::SetCrashDescriptionWithFormat ("%s error: pthread_mutex_destroy() => err = %i (%s)", __PRETTY_FUNCTION__, err, strerror(err));
         assert(err == 0);
@@ -219,7 +284,14 @@
 Mutex::Lock (pthread_mutex_t *mutex_ptr)
 {
     DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr);
+
+#if ENABLE_MUTEX_ERROR_CHECKING
+    error_check_mutex (mutex_ptr, eMutexActionAssertInitialized);
+#endif
+
     int err = ::pthread_mutex_lock (mutex_ptr);
+    
+
 #if ENABLE_MUTEX_ERROR_CHECKING
     if (err)
     {
@@ -234,6 +306,10 @@
 int
 Mutex::TryLock (pthread_mutex_t *mutex_ptr)
 {
+#if ENABLE_MUTEX_ERROR_CHECKING
+    error_check_mutex (mutex_ptr, eMutexActionAssertInitialized);
+#endif
+
     int err = ::pthread_mutex_trylock (mutex_ptr);
     DEBUG_LOG ("[%4.4x/%4.4x] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), mutex_ptr, err);
     return err;
@@ -242,7 +318,12 @@
 int
 Mutex::Unlock (pthread_mutex_t *mutex_ptr)
 {
+#if ENABLE_MUTEX_ERROR_CHECKING
+    error_check_mutex (mutex_ptr, eMutexActionAssertInitialized);
+#endif
+
     int err = ::pthread_mutex_unlock (mutex_ptr);
+
 #if ENABLE_MUTEX_ERROR_CHECKING
     if (err)
     {





More information about the lldb-commits mailing list