Author: bart
Date: 2008-02-27 16:13:05 +0000 (Wed, 27 Feb 2008)
New Revision: 7490

Log:
An error message is now printed before attempting to lock a non-recursive mutex 
recursively.

Added:
   trunk/exp-drd/tests/recursive_mutex.stderr.exp
   trunk/exp-drd/tests/recursive_mutex.stdout.exp
   trunk/exp-drd/tests/recursive_mutex.vgtest
Modified:
   trunk/exp-drd/drd_clientreq.c
   trunk/exp-drd/drd_main.c
   trunk/exp-drd/drd_mutex.c
   trunk/exp-drd/drd_mutex.h
   trunk/exp-drd/tests/recursive_mutex.c


Modified: trunk/exp-drd/drd_clientreq.c
===================================================================
--- trunk/exp-drd/drd_clientreq.c       2008-02-27 15:46:00 UTC (rev 7489)
+++ trunk/exp-drd/drd_clientreq.c       2008-02-27 16:13:05 UTC (rev 7490)
@@ -64,7 +64,7 @@
                                const SizeT size, const MutexT mutex_type)
 {
    cond_post_wait(cond);
-   mutex_lock(mutex, size, mutex_type);
+   mutex_post_lock(mutex, size, mutex_type);
 }
 
 static void drd_pre_cond_signal(const Addr cond)

Modified: trunk/exp-drd/drd_main.c
===================================================================
--- trunk/exp-drd/drd_main.c    2008-02-27 15:46:00 UTC (rev 7489)
+++ trunk/exp-drd/drd_main.c    2008-02-27 16:13:05 UTC (rev 7490)
@@ -431,10 +431,7 @@
                         const SizeT size,
                         const MutexT mutex_type)
 {
-   if (mutex_get(mutex) == 0)
-   {
-      mutex_init(mutex, size, mutex_type);
-   }
+   mutex_pre_lock(mutex, size, mutex_type);
 }
 
 void drd_post_mutex_lock(const DrdThreadId drd_tid,
@@ -442,7 +439,7 @@
                          const SizeT size,
                          const MutexT mutex_type)
 {
-   mutex_lock(mutex, size, mutex_type);
+   mutex_post_lock(mutex, size, mutex_type);
 }
 
 void drd_pre_mutex_unlock(const DrdThreadId drd_tid,

Modified: trunk/exp-drd/drd_mutex.c
===================================================================
--- trunk/exp-drd/drd_mutex.c   2008-02-27 15:46:00 UTC (rev 7489)
+++ trunk/exp-drd/drd_mutex.c   2008-02-27 16:13:05 UTC (rev 7490)
@@ -244,12 +244,40 @@
   return 0;
 }
 
+/** Called before pthread_mutex_lock() is invoked. If a data structure for
+ *  the client-side object was not yet created, do this now. Also check whether
+ *  an attempt is made to lock recursively a synchronization object that must
+ *  not be locked recursively.
+ */
+void mutex_pre_lock(const Addr mutex, const SizeT size, MutexT mutex_type)
+{
+  struct mutex_info* p = mutex_get(mutex);
+  if (p == 0)
+  {
+    mutex_init(mutex, size, mutex_type);
+    p = mutex_get(mutex);
+  }
+  tl_assert(p);
+
+  if (p->owner == thread_get_running_tid()
+      && p->recursion_count >= 1
+      && mutex_type != mutex_type_recursive_mutex)
+  {
+    MutexErrInfo MEI = { p->mutex, p->recursion_count, p->owner };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            MutexErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Recursive locking not allowed",
+                            &MEI);
+  }
+}
+
 /**
  * Update mutex_info state when locking the pthread_mutex_t mutex.
  * Note: this function must be called after pthread_mutex_lock() has been
  * called, or a race condition is triggered !
  */
-int mutex_lock(const Addr mutex, const SizeT size, MutexT mutex_type)
+int mutex_post_lock(const Addr mutex, const SizeT size, MutexT mutex_type)
 {
   const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(VG_(get_running_tid)());
   struct mutex_info* const p = mutex_get_or_allocate(mutex, size, mutex_type);
@@ -286,13 +314,6 @@
   tl_assert(p->mutex_type == mutex_type);
   tl_assert(p->size == size);
 
-  if (p->recursion_count >= 1 && mutex_type == mutex_type_spinlock)
-  {
-    // TO DO: tell the user in a more friendly way that it is not allowed to
-    // lock spinlocks recursively.
-    tl_assert(0);
-  }
-
   if (p->recursion_count == 0)
   {
     p->owner = drd_tid;

Modified: trunk/exp-drd/drd_mutex.h
===================================================================
--- trunk/exp-drd/drd_mutex.h   2008-02-27 15:46:00 UTC (rev 7489)
+++ trunk/exp-drd/drd_mutex.h   2008-02-27 16:13:05 UTC (rev 7490)
@@ -45,7 +45,8 @@
 void mutex_pre_destroy(struct mutex_info* const p);
 void mutex_post_destroy(const Addr mutex);
 struct mutex_info* mutex_get(const Addr mutex);
-int mutex_lock(const Addr mutex, const SizeT size, const MutexT mutex_type);
+void mutex_pre_lock(const Addr mutex, const SizeT size, const MutexT 
mutex_type);
+int mutex_post_lock(const Addr mutex, const SizeT size, const MutexT 
mutex_type);
 int mutex_unlock(const Addr mutex, const MutexT mutex_type);
 const char* mutex_get_typename(struct mutex_info* const p);
 const char* mutex_type_name(const MutexT mt);

Modified: trunk/exp-drd/tests/recursive_mutex.c
===================================================================
--- trunk/exp-drd/tests/recursive_mutex.c       2008-02-27 15:46:00 UTC (rev 
7489)
+++ trunk/exp-drd/tests/recursive_mutex.c       2008-02-27 16:13:05 UTC (rev 
7490)
@@ -1,5 +1,5 @@
-/** Initialize a recursive mutex and lock it twice.
- *  No error messages may be printed.
+/** Initialize several kinds of mutexes and lock each mutex twice.
+ *  Note: locking a regular mutex twice causes a deadlock.
  */
 
 #define _GNU_SOURCE
@@ -17,6 +17,9 @@
 
 int main(int argc, char** argv)
 {
+  /* Let the program abort after 3 seconds instead of leaving it deadlocked. */
+  alarm(3);
+
   {
     pthread_mutex_t m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -51,7 +54,9 @@
     pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
 
     printf("Non-recursive mutex.\n");
+    fflush(stdout);
     lock_twice(&m);
   } 
+  printf("Done.\n");
   return 0;
 }

Added: trunk/exp-drd/tests/recursive_mutex.stderr.exp
===================================================================
--- trunk/exp-drd/tests/recursive_mutex.stderr.exp                              
(rev 0)
+++ trunk/exp-drd/tests/recursive_mutex.stderr.exp      2008-02-27 16:13:05 UTC 
(rev 7490)
@@ -0,0 +1,17 @@
+
+Recursive locking not allowed: address 0x........, recursion count 1, owner 1.
+   at 0x........: pthread_mutex_lock (drd_intercepts.c:?)
+   by 0x........: lock_twice (recursive_mutex.c:?)
+   by 0x........: main (recursive_mutex.c:?)
+
+Attempt to unlock a mutex that is not locked: address 0x........, recursion 
count -1, owner 1.
+   at 0x........: pthread_mutex_unlock (drd_intercepts.c:?)
+   by 0x........: lock_twice (recursive_mutex.c:?)
+   by 0x........: main (recursive_mutex.c:?)
+
+Recursive locking not allowed: address 0x........, recursion count 1, owner 1.
+   at 0x........: pthread_mutex_lock (drd_intercepts.c:?)
+   by 0x........: lock_twice (recursive_mutex.c:?)
+   by 0x........: main (recursive_mutex.c:?)
+
+ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Added: trunk/exp-drd/tests/recursive_mutex.stdout.exp
===================================================================
--- trunk/exp-drd/tests/recursive_mutex.stdout.exp                              
(rev 0)
+++ trunk/exp-drd/tests/recursive_mutex.stdout.exp      2008-02-27 16:13:05 UTC 
(rev 7490)
@@ -0,0 +1,4 @@
+Recursive mutex (statically initialized).
+Recursive mutex (initialized via mutex attributes).
+Error checking mutex.
+Non-recursive mutex.

Added: trunk/exp-drd/tests/recursive_mutex.vgtest
===================================================================
--- trunk/exp-drd/tests/recursive_mutex.vgtest                          (rev 0)
+++ trunk/exp-drd/tests/recursive_mutex.vgtest  2008-02-27 16:13:05 UTC (rev 
7490)
@@ -0,0 +1 @@
+prog: recursive_mutex


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Valgrind-developers mailing list
Valgrind-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to