Added detection of more types of runtime errors. Cleaned up tracing output. Added test for tracing output (tc20_verifywrap2).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7511 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_barrier.c b/exp-drd/drd_barrier.c
index b4fca3d..30c801e 100644
--- a/exp-drd/drd_barrier.c
+++ b/exp-drd/drd_barrier.c
@@ -123,8 +123,13 @@
 
   if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
   {
-    VG_(message)(Vg_UserMsg, "Destruction of barrier 0x%lx being waited upon",
-                 p->a1);
+    BarrierErrInfo bei = { p->a1 };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            BarrierErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Destruction of barrier that is being waited"
+                            " upon",
+                            &bei);
   }
 
   VG_(OSetGen_ResetIter)(p->oset);
@@ -168,6 +173,14 @@
 struct barrier_info*
 barrier_init(const Addr barrier, const SizeT size, const Word count)
 {
+  if (s_trace_barrier)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] barrier_init 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 barrier);
+  }
   tl_assert(barrier_get(barrier) == 0);
   return barrier_get_or_allocate(barrier, size, count);
 }
@@ -175,6 +188,14 @@
 /** Called after pthread_barrier_destroy(). */
 void barrier_destroy(struct barrier_info* const p)
 {
+  if (s_trace_barrier)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] barrier_destroy 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 p->a1);
+  }
   tl_assert(p);
   drd_clientobj_remove(p->a1, ClientBarrier);
 }
@@ -191,9 +212,12 @@
 
   if (s_trace_barrier)
   {
-    VG_(message)(Vg_DebugMsg,
-                 "[%d] barrier_pre_wait(%p) iteration %d",
-                 tid, barrier, p->pre_iteration);
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] barrier_pre_wait 0x%lx iteration %d",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 barrier,
+                 p->pre_iteration);
   }
 
   q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
@@ -218,14 +242,19 @@
 void barrier_post_wait(const DrdThreadId tid, const Addr barrier,
                        const Bool waited)
 {
-  struct barrier_info* const p = barrier_get(barrier);
+  struct barrier_info* p;
 
+  p = barrier_get(barrier);
   tl_assert(p);
 
   if (s_trace_barrier)
   {
-    VG_(message)(Vg_DebugMsg, "[%d] barrier_post_wait(%p) iteration %d",
-                 tid, barrier, p->post_iteration);
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] barrier_post_wait 0x%lx iteration %d",
+                 VG_(get_running_tid)(),
+                 tid,
+                 barrier,
+                 p->post_iteration);
   }
 
   if (waited)
@@ -241,23 +270,7 @@
     {
       if (r != q)
       {
-        if (s_trace_barrier)
-        {
-          VG_(message)(Vg_DebugMsg,
-                       "[%d] barrier_post_wait: combining vc of thread %d, "
-                       "iteration %d",
-                       tid, r->tid, p->post_iteration);
-          vc_print(&thread_get_segment(tid)->vc);
-          VG_(printf)(", ");
-          vc_print(&r->vc[p->post_iteration]);
-          VG_(printf)(" -> ");
-        }
         thread_combine_vc2(tid, &r->vc[p->post_iteration]);
-        if (s_trace_barrier)
-        {
-          vc_print(&thread_get_segment(tid)->vc);
-          VG_(printf)("\n");
-        }
       }
     }
 
diff --git a/exp-drd/drd_clientreq.c b/exp-drd/drd_clientreq.c
index 8d4191c..1de6851 100644
--- a/exp-drd/drd_clientreq.c
+++ b/exp-drd/drd_clientreq.c
@@ -61,10 +61,11 @@
 }
 
 static void drd_post_cond_wait(const Addr cond, const Addr mutex,
-                               const SizeT size, const MutexT mutex_type)
+                               const SizeT size, const MutexT mutex_type,
+                               const Bool took_lock)
 {
    cond_post_wait(cond);
-   mutex_post_lock(mutex, size, mutex_type);
+   mutex_post_lock(mutex, size, mutex_type, took_lock);
 }
 
 static void drd_pre_cond_signal(const Addr cond)
@@ -144,7 +145,8 @@
       break;
 
    case VG_USERREQ__POST_PTHREAD_MUTEX_LOCK:
-      drd_post_mutex_lock(thread_get_running_tid(), arg[1], arg[2], arg[3]);
+      drd_post_mutex_lock(thread_get_running_tid(),
+                          arg[1], arg[2], arg[3], arg[4]);
       break;
 
    case VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK:
@@ -170,7 +172,8 @@
 
    case VG_USERREQ__POST_PTHREAD_COND_WAIT:
       drd_post_cond_wait(arg[1]/*cond*/, arg[2]/*mutex*/,
-                         arg[3]/*mutex_size*/, arg[4]/*mutex_type*/);
+                         arg[3]/*mutex_size*/, arg[4]/*mutex_type*/,
+                         arg[5]/*took_lock*/);
       break;
 
    case VG_USERREQ__PRE_PTHREAD_COND_SIGNAL:
diff --git a/exp-drd/drd_clientreq.h b/exp-drd/drd_clientreq.h
index a41e8d6..68cf741 100644
--- a/exp-drd/drd_clientreq.h
+++ b/exp-drd/drd_clientreq.h
@@ -63,7 +63,7 @@
   /* args: Addr, SizeT, MutexT */
   /* to notify the drd tool of pthread_mutex_lock calls */
   VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-  /* args: Addr, SizeT, MutexT */
+  /* args: Addr, SizeT, MutexT, Bool */
   /* to notify the drd tool of pthread_mutex_unlock calls */
   VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
   /* args: Addr */
@@ -76,11 +76,11 @@
   /* args: Addr */
   /* to notify the drd tool of a pthread_cond_destroy call. */
   VG_USERREQ__PRE_PTHREAD_COND_DESTROY,
-  /* args: Addr cond, SizeT cond_size, Addr mutex, SizeT mutex_size, MutexT mt */
+  /* args: Addr cond, SizeT cond_size, Addr mutex, SizeT mutex_size,MutexT mt*/
   VG_USERREQ__PRE_PTHREAD_COND_WAIT,
   /* args: Addr cond, SizeT cond_size, Addr mutex, MutexT mt */
   VG_USERREQ__POST_PTHREAD_COND_WAIT,
-  /* args: Addr cond, Addr mutex, SizeT mutex_size, MutexT mt */
+  /* args: Addr cond, Addr mutex, SizeT mutex_size, MutexT mt, Bool took_lock*/
   VG_USERREQ__PRE_PTHREAD_COND_SIGNAL,
   /* args: Addr cond */
   VG_USERREQ__PRE_PTHREAD_COND_BROADCAST,
diff --git a/exp-drd/drd_cond.c b/exp-drd/drd_cond.c
index 3de2f3b..4e2dbd0 100644
--- a/exp-drd/drd_cond.c
+++ b/exp-drd/drd_cond.c
@@ -77,10 +77,16 @@
   {
     struct mutex_info* q;
     q = &drd_clientobj_get(p->mutex, ClientMutex)->mutex;
-    VG_(message)(Vg_UserMsg,
-                 "Error: destroying condition variable 0x%lx while thread %d"
-                 " is waiting on it.\n",
-                 p->a1, q ? q->owner : -1);
+    tl_assert(q);
+    {
+      CondDestrErrInfo cde = { p->a1, q->a1, q->owner };
+      VG_(maybe_record_error)(VG_(get_running_tid)(),
+                              CondDestrErr,
+                              VG_(get_IP)(VG_(get_running_tid)()),
+                              "Destroying condition variable that is being"
+                              " waited upon",
+                              &cde);
+    }
   }
 }
 
@@ -110,8 +116,11 @@
 {
   if (s_trace_cond)
   {
-    VG_(message)(Vg_UserMsg, "Initializing condition variable 0x%lx", cond);
-    VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_init 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 cond);
   }
   tl_assert(cond_get(cond) == 0);
   tl_assert(size > 0);
@@ -123,8 +132,11 @@
 {
   if (s_trace_cond)
   {
-    VG_(message)(Vg_UserMsg, "Destroying condition variable 0x%lx", p->a1);
-    VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_destroy 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 p->a1);
   }
 
   // TO DO: print a proper error message if waiter_count != 0.
@@ -138,7 +150,18 @@
 {
   struct cond_info* p;
 
+  if (s_trace_cond)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_pre_wait 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 cond);
+  }
+
   p = cond_get_or_allocate(cond, cond_size);
+  tl_assert(p);
+
   if (p->waiter_count == 0)
   {
     p->mutex = mutex;
@@ -158,6 +181,15 @@
 {
   struct cond_info* p;
 
+  if (s_trace_cond)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_post_wait 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 cond);
+  }
+
   p = cond_get(cond);
   tl_assert(p);
   tl_assert(p->waiter_count > 0);
@@ -169,12 +201,12 @@
   return p->waiter_count;
 }
 
-/** Called before pthread_cond_signal(). */
-void cond_pre_signal(Addr const cond)
+static void cond_signal(Addr const cond)
 {
   const ThreadId vg_tid = VG_(get_running_tid)();
   const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
   struct cond_info* const cond_p = cond_get(cond);
+
   if (cond_p && cond_p->waiter_count > 0)
   {
     if (! mutex_is_locked_by(cond_p->mutex, drd_tid))
@@ -196,10 +228,34 @@
   }
 }
 
+/** Called before pthread_cond_signal(). */
+void cond_pre_signal(Addr const cond)
+{
+  if (s_trace_cond)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_signal 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 cond);
+  }
+
+  cond_signal(cond);
+}
+
 /** Called before pthread_cond_broadcast(). */
 void cond_pre_broadcast(Addr const cond)
 {
-  cond_pre_signal(cond);
+  if (s_trace_cond)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] cond_broadcast 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 cond);
+  }
+
+  cond_signal(cond);
 }
 
 /** Called after pthread_cond_destroy(). */
diff --git a/exp-drd/drd_error.c b/exp-drd/drd_error.c
index 5e63e7c..60f31d7 100644
--- a/exp-drd/drd_error.c
+++ b/exp-drd/drd_error.c
@@ -269,16 +269,6 @@
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
-   case CondRaceErr: {
-      CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
-      VG_(message)(Vg_UserMsg,
-                   "Race condition: condition variable 0x%lx has been signalled"
-                   " but the associated mutex 0x%lx is not locked by the"
-                   " signalling thread",
-                   cei->cond, cei->mutex);
-      VG_(pp_ExeContext)(VG_(get_error_where)(e));
-      break;
-   }
    case CondErr: {
       CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
       VG_(message)(Vg_UserMsg,
@@ -288,6 +278,44 @@
       VG_(pp_ExeContext)(VG_(get_error_where)(e));
       break;
    }
+   case CondRaceErr: {
+      CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
+      VG_(message)(Vg_UserMsg,
+                   "Race condition: condition variable 0x%lx has been"
+                   " signalled but the associated mutex 0x%lx is not locked"
+                   " by the signalling thread",
+                   cei->cond, cei->mutex);
+      VG_(pp_ExeContext)(VG_(get_error_where)(e));
+      break;
+   }
+   case CondDestrErr: {
+      CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
+      VG_(message)(Vg_UserMsg,
+                   "%s: cond 0x%lx, mutex 0x%lx locked by thread %d",
+                   cdi->cond, cdi->mutex, cdi->tid);
+      VG_(pp_ExeContext)(VG_(get_error_where)(e));
+      break;
+   }
+   case SemaphoreErr: {
+      SemaphoreErrInfo* sei =(SemaphoreErrInfo*)(VG_(get_error_extra)(e));
+      tl_assert(sei);
+      VG_(message)(Vg_UserMsg,
+                   "%s 0x%lx",
+                   VG_(get_error_string)(e),
+                   sei->semaphore);
+      VG_(pp_ExeContext)(VG_(get_error_where)(e));
+      break;
+   }
+   case BarrierErr: {
+      BarrierErrInfo* sei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
+      tl_assert(sei);
+      VG_(message)(Vg_UserMsg,
+                   "%s: barrier 0x%lx",
+                   VG_(get_error_string)(e),
+                   sei->barrier);
+      VG_(pp_ExeContext)(VG_(get_error_where)(e));
+      break;
+   }
    case GenericErr: {
       //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
       VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
@@ -311,10 +339,16 @@
       return sizeof(DataRaceErrInfo);
    case MutexErr:
       return sizeof(MutexErrInfo);
-   case CondRaceErr:
-      return sizeof(CondRaceErrInfo);
    case CondErr:
       return sizeof(CondErrInfo);
+   case CondRaceErr:
+      return sizeof(CondRaceErrInfo);
+   case CondDestrErr:
+      return sizeof(CondDestrErrInfo);
+   case SemaphoreErr:
+      return sizeof(SemaphoreErrInfo);
+   case BarrierErr:
+      return sizeof(BarrierErrInfo);
    case GenericErr:
       return sizeof(GenericErrInfo);
    default:
diff --git a/exp-drd/drd_error.h b/exp-drd/drd_error.h
index e9a54c4..9dfdd61 100644
--- a/exp-drd/drd_error.h
+++ b/exp-drd/drd_error.h
@@ -39,9 +39,12 @@
 typedef enum {
    DataRaceErr    = 1,
    MutexErr       = 2,
-   CondRaceErr    = 3,
-   CondErr        = 4,
-   GenericErr     = 5,
+   CondErr        = 3,
+   CondRaceErr    = 4,
+   CondDestrErr   = 5,
+   SemaphoreErr   = 6,
+   BarrierErr     = 7,
+   GenericErr     = 8,
 } DrdErrorKind;
 
 /* The classification of a faulting address. */
@@ -88,12 +91,26 @@
 
 typedef struct {
    Addr cond;
+} CondErrInfo;
+
+typedef struct {
+   Addr cond;
    Addr mutex;
 } CondRaceErrInfo;
 
 typedef struct {
-   Addr cond;
-} CondErrInfo;
+   Addr        cond;
+   Addr        mutex;
+   DrdThreadId tid;
+} CondDestrErrInfo;
+
+typedef struct {
+   Addr semaphore;
+} SemaphoreErrInfo;
+
+typedef struct {
+   Addr barrier;
+} BarrierErrInfo;
 
 typedef struct {
 } GenericErrInfo;
diff --git a/exp-drd/drd_intercepts.c b/exp-drd/drd_intercepts.c
index 2a56978..6e14d63 100644
--- a/exp-drd/drd_intercepts.c
+++ b/exp-drd/drd_intercepts.c
@@ -343,9 +343,9 @@
    write(1, "", 0);
 #endif
    CALL_FN_W_W(ret, fn, mutex);
-   if (ret == 0)
-      VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-                                mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
+   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+                              mutex, sizeof(*mutex), mutex_type(mutex),
+                              ret == 0, 0);
    return ret;
 }
 
@@ -358,11 +358,9 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_W(ret, fn, mutex);
-   if (ret == 0)
-   {
-      VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-                                mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
-   }
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+                              mutex, sizeof(*mutex), mutex_type(mutex),
+                              ret == 0, 0);
    return ret;
 }
 
@@ -376,11 +374,9 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
-   if (ret == 0)
-   {
-      VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-                                mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
-   }
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+                              mutex, sizeof(*mutex), mutex_type(mutex),
+                              ret == 0, 0);
    return ret;
 }
 
@@ -438,10 +434,12 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
-                              cond, sizeof(*cond), mutex, mutex_type(mutex), 0);
+                              cond, sizeof(*cond), mutex, mutex_type(mutex),
+                              0);
    CALL_FN_W_WW(ret, fn, cond, mutex);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
-                              cond, mutex, sizeof(*mutex), mutex_type(mutex), 0);
+                              cond, mutex, sizeof(*mutex), mutex_type(mutex),
+                              ret == 0);
    return ret;
 }
 
@@ -456,10 +454,12 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
-                              cond, sizeof(*cond), mutex, mutex_type(mutex), 0);
+                              cond, sizeof(*cond), mutex, mutex_type(mutex),
+                              0);
    CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
-                              cond, mutex, sizeof(*mutex), mutex_type(mutex), 0);
+                              cond, mutex, sizeof(*mutex), mutex_type(mutex),
+                              ret == 0);
    return ret;
 }
 
@@ -531,12 +531,9 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_W(ret, fn, spinlock);
-   if (ret == 0)
-   {
-      VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-                                 spinlock, sizeof(*spinlock),
-                                 mutex_type_spinlock, 0, 0);
-   }
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+                              spinlock, sizeof(*spinlock),
+                              mutex_type_spinlock, ret == 0, 0);
    return ret;
 }
 
@@ -549,12 +546,9 @@
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_W(ret, fn, spinlock);
-   if (ret == 0)
-   {
-      VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
-                                 spinlock, sizeof(*spinlock),
-                                 mutex_type_spinlock, 0, 0);
-   }
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+                              spinlock, sizeof(*spinlock),
+                              mutex_type_spinlock, ret == 0, 0);
    return ret;
 }
 
diff --git a/exp-drd/drd_main.c b/exp-drd/drd_main.c
index 5b8b436..af447f3 100644
--- a/exp-drd/drd_main.c
+++ b/exp-drd/drd_main.c
@@ -428,9 +428,10 @@
 void drd_post_mutex_lock(const DrdThreadId drd_tid,
                          const Addr mutex,
                          const SizeT size,
-                         const MutexT mutex_type)
+                         const MutexT mutex_type,
+                         const Bool took_lock)
 {
-   mutex_post_lock(mutex, size, mutex_type);
+   mutex_post_lock(mutex, size, mutex_type, took_lock);
 }
 
 void drd_pre_mutex_unlock(const DrdThreadId drd_tid,
diff --git a/exp-drd/drd_mutex.c b/exp-drd/drd_mutex.c
index ac8ddfe..568bf4d 100644
--- a/exp-drd/drd_mutex.c
+++ b/exp-drd/drd_mutex.c
@@ -78,11 +78,10 @@
 {
   if (s_trace_mutex)
   {
-    const ThreadId vg_tid = VG_(get_running_tid)();
-    const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
-    VG_(message)(Vg_DebugMsg,
-                 "drd_pre_mutex_destroy tid = %d/%d, %s 0x%lx",
-                 vg_tid, drd_tid,
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] mutex_destroy   %s 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
                  mutex_get_typename(p),
                  p->a1);
   }
@@ -133,6 +132,12 @@
   return p;
 }
 
+struct mutex_info* mutex_get(const Addr mutex)
+{
+  tl_assert(offsetof(DrdClientobj, mutex) == 0);
+  return &drd_clientobj_get(mutex, ClientMutex)->mutex;
+}
+
 struct mutex_info*
 mutex_init(const Addr mutex, const SizeT size, const MutexT mutex_type)
 {
@@ -140,11 +145,10 @@
 
   if (s_trace_mutex)
   {
-    const ThreadId vg_tid = VG_(get_running_tid)();
-    const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
-    VG_(message)(Vg_DebugMsg,
-                 "drd_post_mutex_init  tid = %d/%d, %s 0x%lx",
-                 vg_tid, drd_tid,
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] mutex_init      %s 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
                  mutex_type_name(mutex_type),
                  mutex);
   }
@@ -185,12 +189,6 @@
    }
 }
 
-struct mutex_info* mutex_get(const Addr mutex)
-{
-  tl_assert(offsetof(DrdClientobj, mutex) == 0);
-  return &drd_clientobj_get(mutex, ClientMutex)->mutex;
-}
-
 /** 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
@@ -227,17 +225,17 @@
  * Note: this function must be called after pthread_mutex_lock() has been
  * called, or a race condition is triggered !
  */
-int mutex_post_lock(const Addr mutex, const SizeT size, MutexT mutex_type)
+int mutex_post_lock(const Addr mutex, const SizeT size, MutexT mutex_type,
+                    const Bool took_lock)
 {
-  const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(VG_(get_running_tid)());
+  const DrdThreadId drd_tid = thread_get_running_tid();
   struct mutex_info* const p = mutex_get_or_allocate(mutex, size, mutex_type);
 
   if (s_trace_mutex)
   {
-    const ThreadId tid = DrdThreadIdToVgThreadId(drd_tid);
-    VG_(message)(Vg_DebugMsg,
-                 "drd_post_mutex_lock  tid = %d/%d, %s 0x%lx rc %d owner %d",
-                 tid,
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] post_mutex_lock %s 0x%lx rc %d owner %d",
+                 VG_(get_running_tid)(),
                  drd_tid,
                  mutex_get_typename(p),
                  mutex,
@@ -266,10 +264,8 @@
      return 0;
   }
 
-#if 0
-  tl_assert(mutex_type == mutex_type_mutex
-            || mutex_type == mutex_type_spinlock);
-#endif
+  if (! took_lock)
+     return p->recursion_count;
 
   tl_assert(p->mutex_type == mutex_type);
   tl_assert(p->a2 - p->a1 == size);
@@ -281,7 +277,7 @@
   }
   else if (p->owner != drd_tid)
   {
-    VG_(message)(Vg_DebugMsg,
+    VG_(message)(Vg_UserMsg,
                  "The impossible happened: mutex 0x%lx is locked"
                  " simultaneously by two threads (recursion count %d,"
                  " owners %d and %d) !",
@@ -320,9 +316,10 @@
 
   if (s_trace_mutex && p != 0)
   {
-    VG_(message)(Vg_DebugMsg,
-                 "drd_pre_mutex_unlock tid = %d/%d, %s 0x%lx rc %d",
-                 vg_tid, drd_tid,
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] mutex_unlock    %s 0x%lx rc %d",
+                 vg_tid,
+                 drd_tid,
                  mutex_get_typename(p),
                  mutex,
                  p->recursion_count,
@@ -364,7 +361,7 @@
   tl_assert(p);
   if (p->mutex_type != mutex_type)
   {
-    VG_(message)(Vg_DebugMsg, "??? mutex %p: type changed from %d into %d",
+    VG_(message)(Vg_UserMsg, "??? mutex %p: type changed from %d into %d",
 	         p->a1, p->mutex_type, mutex_type);
   }
   tl_assert(p->mutex_type == mutex_type);
diff --git a/exp-drd/drd_mutex.h b/exp-drd/drd_mutex.h
index 5c5c7a0..5c12c2b 100644
--- a/exp-drd/drd_mutex.h
+++ b/exp-drd/drd_mutex.h
@@ -44,8 +44,10 @@
                               const MutexT mutex_type);
 void mutex_post_destroy(const Addr mutex);
 struct mutex_info* mutex_get(const Addr mutex);
-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);
+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, const Bool took_lock);
 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);
diff --git a/exp-drd/drd_semaphore.c b/exp-drd/drd_semaphore.c
index 51a15ae..513dcd1 100644
--- a/exp-drd/drd_semaphore.c
+++ b/exp-drd/drd_semaphore.c
@@ -78,8 +78,13 @@
 {
   if (p->waiters > 0)
   {
-    VG_(message)(Vg_UserMsg, "Error: destroying semaphore while %d threads are"
-                 "still waiting on the semaphore.\n", p->waiters);
+    SemaphoreErrInfo sei = { p->a1 };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            SemaphoreErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Destruction of semaphore that is being waited"
+                            " upon",
+                            &sei);
   }
   vc_cleanup(&p->vc);
 }
@@ -114,6 +119,14 @@
 {
   struct semaphore_info* p;
 
+  if (s_trace_semaphore)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] semaphore_init 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 semaphore);
+  }
   tl_assert(semaphore_get(semaphore) == 0);
   p = semaphore_get_or_allocate(semaphore, size);
   p->value = value;
@@ -123,6 +136,17 @@
 /** Called after sem_destroy(). */
 void semaphore_destroy(struct semaphore_info* const p)
 {
+  tl_assert(p);
+
+  if (s_trace_semaphore)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] semaphore_destroy 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 p->a1);
+  }
+
   drd_clientobj_remove(p->a1, ClientSemaphore);
 }
 
@@ -134,7 +158,11 @@
   p = semaphore_get_or_allocate(semaphore, size);
   if (s_trace_semaphore)
   {
-    VG_(message)(Vg_UserMsg, "semaphore_pre_wait(0x%lx, %d)", semaphore, size);
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] semaphore_pre_wait 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 semaphore);
   }
   tl_assert(p);
   tl_assert(p->waiters >= 0);
@@ -154,7 +182,11 @@
   p = semaphore_get(semaphore);
   if (s_trace_semaphore)
   {
-    VG_(message)(Vg_UserMsg, "semaphore_post_wait(0x%lx, %d)", semaphore);
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] semaphore_post_wait 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 semaphore);
   }
   tl_assert(p->waiters > 0);
   p->waiters--;
@@ -162,7 +194,12 @@
   tl_assert(p->value >= 0);
   if (p->value == 0)
   {
-    VG_(message)(Vg_UserMsg, "Invalid semaphore 0x%lx", semaphore);
+    SemaphoreErrInfo sei = { semaphore };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            SemaphoreErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Invalid semaphore",
+                            &sei);
     return;
   }
   p->value--;
@@ -178,6 +215,14 @@
 {
   struct semaphore_info* p;
 
+  if (s_trace_semaphore)
+  {
+    VG_(message)(Vg_UserMsg,
+                 "[%d/%d] semaphore_post 0x%lx",
+                 VG_(get_running_tid)(),
+                 thread_get_running_tid(),
+                 semaphore);
+  }
   p = semaphore_get_or_allocate(semaphore, size);
   p->value++;
   if (p->value == 1)
diff --git a/exp-drd/drd_track.h b/exp-drd/drd_track.h
index e5e2368..1c71c84 100644
--- a/exp-drd/drd_track.h
+++ b/exp-drd/drd_track.h
@@ -30,7 +30,7 @@
 void drd_pre_mutex_lock(DrdThreadId tid, Addr mutex, const SizeT size,
                         const MutexT mutex_type);
 void drd_post_mutex_lock(DrdThreadId tid, Addr mutex, const SizeT size,
-                         const MutexT mutex_type);
+                         const MutexT mutex_type, const Bool took_lock);
 void drd_pre_mutex_unlock(const DrdThreadId tid, const Addr mutex,
                           const MutexT mutex_type);
 
diff --git a/exp-drd/tests/Makefile.am b/exp-drd/tests/Makefile.am
index 6e036bf..30657ed 100644
--- a/exp-drd/tests/Makefile.am
+++ b/exp-drd/tests/Makefile.am
@@ -91,8 +91,9 @@
 	tc19_shadowmem.vgtest                                   \
 	tc19_shadowmem.stderr.exp                               \
 	tc20_verifywrap.vgtest                                  \
-	tc20_verifywrap.stderr.exp                              \
-	tc20_verifywrap.stderr.exp2				\
+	tc20_verifywrap.stderr.exp tc20_verifywrap.stderr.exp2	\
+	tc20_verifywrap2.vgtest                                 \
+	tc20_verifywrap2.stderr.exp tc20_verifywrap2.stderr.exp2\
 	tc21_pthonce.vgtest                                     \
 	tc21_pthonce.stderr.exp tc21_pthonce.stdout.exp         \
 	tc22_exit_w_lock.vgtest                                 \
diff --git a/exp-drd/tests/tc18_semabuse.stderr.exp b/exp-drd/tests/tc18_semabuse.stderr.exp
index d18786f..dd53466 100644
--- a/exp-drd/tests/tc18_semabuse.stderr.exp
+++ b/exp-drd/tests/tc18_semabuse.stderr.exp
@@ -1,3 +1,6 @@
 
+Invalid semaphore 0x........
+   at 0x........: sem_wait* (drd_intercepts.c:?)
+   by 0x........: main (tc18_semabuse.c:34)
 
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
diff --git a/exp-drd/tests/tc20_verifywrap.stderr.exp2 b/exp-drd/tests/tc20_verifywrap.stderr.exp2
index b5115ca..e4bfdeb 100644
--- a/exp-drd/tests/tc20_verifywrap.stderr.exp2
+++ b/exp-drd/tests/tc20_verifywrap.stderr.exp2
@@ -21,6 +21,18 @@
    by 0x........: main (tc20_verifywrap.c:102)
 
 Invalid mutex
+   at 0x........: pthread_mutex_lock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:108)
+
+Invalid mutex
+   at 0x........: pthread_mutex_trylock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:116)
+
+Invalid mutex
+   at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:121)
+
+Invalid mutex
    at 0x........: pthread_mutex_unlock (drd_intercepts.c:?)
    by 0x........: main (tc20_verifywrap.c:125)
 
@@ -41,6 +53,10 @@
 FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
 
 
+Mutex not locked: address 0x........, recursion count 0, owner 0.
+   at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:165)
+
 ---------------- pthread_rwlock_* ----------------
 
 (1) no error on next line
@@ -58,6 +74,10 @@
 FIXME: can't figure out how to verify wrap of sem_destroy
 
 
+Invalid semaphore 0x........
+   at 0x........: sem_wait* (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:242)
+
 FIXME: can't figure out how to verify wrap of sem_post
 
 
@@ -67,4 +87,4 @@
 Destroying locked mutex: address 0x........, recursion count 1, owner 1.
    at 0x........: main (tc20_verifywrap.c:262)
 
-ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0)
diff --git a/exp-drd/tests/tc20_verifywrap2.stderr.exp b/exp-drd/tests/tc20_verifywrap2.stderr.exp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.stderr.exp
diff --git a/exp-drd/tests/tc20_verifywrap2.stderr.exp2 b/exp-drd/tests/tc20_verifywrap2.stderr.exp2
new file mode 100644
index 0000000..a05efce
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.stderr.exp2
@@ -0,0 +1,151 @@
+
+
+
+------ This is output for >= glibc 2.4 ------
+
+---------------- pthread_create/join ----------------
+
+[1/1] mutex_init      recursive mutex 0x........
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+Conflicting store by thread 1 at 0x........ size 2
+   at 0x........: main (tc20_verifywrap.c:78)
+Allocation context: unknown
+Other segment start (thread 2)
+   (thread finished, call stack no longer available)
+Other segment end (thread 2)
+   (thread finished, call stack no longer available)
+
+---------------- pthread_mutex_lock et al ----------------
+
+[1/1] mutex_init      invalid mutex 0x........
+[1/1] mutex_init      mutex 0x........
+[1/1] post_mutex_lock mutex 0x........ rc 0 owner 0
+[1/1] mutex_destroy   mutex 0x........
+
+Destroying locked mutex: address 0x........, recursion count 1, owner 1.
+   at 0x........: pthread_mutex_destroy (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:102)
+[1/1] mutex_init      invalid mutex 0x........
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+
+Invalid mutex
+   at 0x........: pthread_mutex_lock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:108)
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+
+Invalid mutex
+   at 0x........: pthread_mutex_trylock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:116)
+[1/1] post_mutex_lock invalid mutex 0x........ rc 0 owner 0
+
+Invalid mutex
+   at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:121)
+[1/1] mutex_unlock    invalid mutex 0x........ rc 0
+
+Invalid mutex
+   at 0x........: pthread_mutex_unlock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:125)
+
+Mutex not locked: address 0x........, recursion count 0, owner 0.
+   at 0x........: pthread_mutex_unlock (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:125)
+
+---------------- pthread_cond_wait et al ----------------
+
+[1/1] mutex_init      error checking mutex 0x........
+[1/1] cond_init 0x........
+[1/1] mutex_unlock    error checking mutex 0x........ rc 0
+
+Mutex not locked: address 0x........, recursion count 0, owner 0.
+   at 0x........: pthread_cond_wait* (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:147)
+[1/1] cond_pre_wait 0x........
+[1/1] cond_post_wait 0x........
+[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0
+[1/1] cond_signal 0x........
+
+FIXME: can't figure out how to verify wrap of pthread_cond_signal
+
+[1/1] cond_broadcast 0x........
+
+FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
+
+[1/1] mutex_unlock    error checking mutex 0x........ rc 0
+
+Mutex not locked: address 0x........, recursion count 0, owner 0.
+   at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:165)
+[1/1] cond_pre_wait 0x........
+[1/1] cond_post_wait 0x........
+[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0
+
+---------------- pthread_rwlock_* ----------------
+
+(1) no error on next line
+(2) no error on next line
+(3)    ERROR on next line
+(4) no error on next line
+(5) no error on next line
+(6) no error on next line
+(7) no error on next line
+(8)    ERROR on next line
+
+---------------- sem_* ----------------
+
+[1/1] semaphore_init 0x........
+
+FIXME: can't figure out how to verify wrap of sem_destroy
+
+[1/1] semaphore_pre_wait 0x........
+[1/1] semaphore_post_wait 0x........
+
+Invalid semaphore 0x........
+   at 0x........: sem_wait* (drd_intercepts.c:?)
+   by 0x........: main (tc20_verifywrap.c:242)
+[1/1] semaphore_post 0x........
+
+FIXME: can't figure out how to verify wrap of sem_post
+
+[1/1] semaphore_destroy 0x........
+
+------------ dealloc of mem holding locks ------------
+
+[1/1] mutex_destroy   error checking mutex 0x........
+[1/1] mutex_destroy   invalid mutex 0x........
+[1/1] mutex_destroy   invalid mutex 0x........
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock    recursive mutex 0x........ rc 1
+
+ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0)
diff --git a/exp-drd/tests/tc20_verifywrap2.vgtest b/exp-drd/tests/tc20_verifywrap2.vgtest
new file mode 100644
index 0000000..d7223f2
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.vgtest
@@ -0,0 +1,2 @@
+prog: tc20_verifywrap
+vgopts: --trace-mutex=yes --trace-cond=yes --trace-semaphore=yes