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