An error message is now printed if the mutex pointer passed to
pthread_cond_wait() does not point to a mutex object, and also if the
mutex pointer passed to pthread_cond_wait() points to a recursive mutex
that has been locked recursively.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8301 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_cond.c b/exp-drd/drd_cond.c
index 7cdd581..c5b04a4 100644
--- a/exp-drd/drd_cond.c
+++ b/exp-drd/drd_cond.c
@@ -182,10 +182,13 @@
   clientobj_remove(p->a1, ClientCondvar);
 }
 
-/** Called before pthread_cond_wait(). */
+/** Called before pthread_cond_wait(). Note: before this function is called,
+ *  mutex_unlock() has already been called from drd_clientreq.c.
+ */
 int cond_pre_wait(const Addr cond, const Addr mutex)
 {
   struct cond_info* p;
+  struct mutex_info* q;
 
   if (s_trace_cond)
   {
@@ -214,6 +217,23 @@
                             " and mutex",
                             &cwei);
   }
+  tl_assert(p->mutex);
+  q = mutex_get(p->mutex);
+  if (q && q->recursion_count > 0)
+  {
+    const ThreadId vg_tid = VG_(get_running_tid)();
+    MutexErrInfo MEI = { q->a1, q->recursion_count, q->owner };
+    VG_(maybe_record_error)(vg_tid,
+                            MutexErr,
+                            VG_(get_IP)(vg_tid),
+                            "Mutex locked recursively",
+                            &MEI);
+  }
+  else if (q == 0)
+  {
+    not_a_mutex(p->mutex);
+  }
+
   return ++p->waiter_count;
 }