Added command-line option --trace-clientobj. Renamed drd_clientobj* functions into clientobj*. Moved some code from drd_main.c into the drd_mutex.c/drd_cond.c/drd_semaphore.c.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7522 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_barrier.c b/exp-drd/drd_barrier.c
index 30c801e..9a135b3 100644
--- a/exp-drd/drd_barrier.c
+++ b/exp-drd/drd_barrier.c
@@ -113,7 +113,7 @@
 }
 
 /** Deallocate the memory allocated by barrier_initialize() and in p->oset. 
- *  Called by drd_clientobj_destroy().
+ *  Called by clientobj_destroy().
  */
 void barrier_cleanup(struct barrier_info* p)
 {
@@ -149,10 +149,10 @@
   struct barrier_info *p;
 
   tl_assert(offsetof(DrdClientobj, barrier) == 0);
-  p = &drd_clientobj_get(barrier, ClientBarrier)->barrier;
+  p = &clientobj_get(barrier, ClientBarrier)->barrier;
   if (p == 0)
   {
-    p = &drd_clientobj_add(barrier, barrier + size, ClientBarrier)->barrier;
+    p = &clientobj_add(barrier, barrier + size, ClientBarrier)->barrier;
     barrier_initialize(p, barrier, size, count);
   }
   return p;
@@ -160,10 +160,10 @@
 
 /** Look up the address of the information associated with the client-side
  *  barrier object. */
-struct barrier_info* barrier_get(const Addr barrier)
+static struct barrier_info* barrier_get(const Addr barrier)
 {
   tl_assert(offsetof(DrdClientobj, barrier) == 0);
-  return &drd_clientobj_get(barrier, ClientBarrier)->barrier;
+  return &clientobj_get(barrier, ClientBarrier)->barrier;
 }
 
 /** Initialize a barrier with client address barrier, client size size, and
@@ -186,18 +186,32 @@
 }
 
 /** Called after pthread_barrier_destroy(). */
-void barrier_destroy(struct barrier_info* const p)
+void barrier_destroy(const Addr barrier)
 {
+  struct barrier_info* 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);
+                 barrier);
   }
-  tl_assert(p);
-  drd_clientobj_remove(p->a1, ClientBarrier);
+
+  p = barrier_get(barrier);
+  if (p == 0)
+  {
+    GenericErrInfo GEI;
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            GenericErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Not a barrier",
+                            &GEI);
+    return;
+  }
+
+  clientobj_remove(p->a1, ClientBarrier);
 }
 
 /** Called before pthread_barrier_wait(). */
@@ -289,8 +303,8 @@
 {
   struct barrier_info* p;
 
-  drd_clientobj_resetiter();
-  for ( ; (p = &drd_clientobj_next(ClientBarrier)->barrier) != 0; )
+  clientobj_resetiter();
+  for ( ; (p = &clientobj_next(ClientBarrier)->barrier) != 0; )
   {
     struct barrier_thread_info* q;
     const UWord word_tid = tid;
diff --git a/exp-drd/drd_barrier.h b/exp-drd/drd_barrier.h
index 36ee98d..4351d04 100644
--- a/exp-drd/drd_barrier.h
+++ b/exp-drd/drd_barrier.h
@@ -41,8 +41,7 @@
 void barrier_set_trace(const Bool trace_barrier);
 struct barrier_info* barrier_init(const Addr barrier, const SizeT size,
                                   const Word count);
-void barrier_destroy(struct barrier_info* const p);
-struct barrier_info* barrier_get(const Addr barrier);
+void barrier_destroy(const Addr barrier);
 void barrier_pre_wait(const DrdThreadId tid, const Addr barrier);
 void barrier_post_wait(const DrdThreadId tid, const Addr barrier,
                        const Bool waited);
diff --git a/exp-drd/drd_clientobj.c b/exp-drd/drd_clientobj.c
index 56fb65e..0ccf2bf 100644
--- a/exp-drd/drd_clientobj.c
+++ b/exp-drd/drd_clientobj.c
@@ -28,20 +28,29 @@
 #include "pub_tool_basics.h"
 #include "pub_tool_libcassert.h"
 #include "pub_tool_libcbase.h"
-#include "pub_tool_libcprint.h"  // VG_(message)()
+#include "pub_tool_libcprint.h"   // VG_(message)()
 #include "pub_tool_mallocfree.h"
+#include "pub_tool_options.h"     // VG_(clo_backtrace_size)
 #include "pub_tool_oset.h"
+#include "pub_tool_stacktrace.h"
+#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
 
 
 // Local variables.
 
 static OSet* s_clientobj;
+static Bool s_trace_clientobj;
 
 
 // Function definitions.
 
+void clientobj_set_trace(const Bool trace)
+{
+  s_trace_clientobj = trace;
+}
+
 /** Initialize the client object set. */
-void drd_clientobj_init(void)
+void clientobj_init(void)
 {
   tl_assert(s_clientobj == 0);
   s_clientobj = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
@@ -51,7 +60,7 @@
 /** Free the memory allocated for the client object set.
  *  @pre Client object set is empty.
  */
-void drd_clientobj_cleanup(void)
+void clientobj_cleanup(void)
 {
   tl_assert(s_clientobj);
   tl_assert(VG_(OSetGen_Size)(s_clientobj) == 0);
@@ -63,7 +72,7 @@
  *  and that has object type t. Return 0 if there is no client object in the
  *  set with the specified start address.
  */
-DrdClientobj* drd_clientobj_get(const Addr addr, const ObjType t)
+DrdClientobj* clientobj_get(const Addr addr, const ObjType t)
 {
   DrdClientobj* p;
   p = VG_(OSetGen_Lookup)(s_clientobj, &addr);
@@ -75,7 +84,7 @@
 /** Return true if and only if the address range of any client object overlaps
  *  with the specified address range.
  */
-Bool drd_clientobj_present(const Addr a1, const Addr a2)
+Bool clientobj_present(const Addr a1, const Addr a2)
 {
   DrdClientobj *p;
 
@@ -97,14 +106,19 @@
  *  @pre No other client object is present in the address range [addr,addr+size[.
  */
 DrdClientobj*
-drd_clientobj_add(const Addr a1, const Addr a2, const ObjType t)
+clientobj_add(const Addr a1, const Addr a2, const ObjType t)
 {
   DrdClientobj* p;
 
   tl_assert(a1 < a2 && a1 + 4096 > a2);
-  tl_assert(! drd_clientobj_present(a1, a2));
+  tl_assert(! clientobj_present(a1, a2));
   tl_assert(VG_(OSetGen_Lookup)(s_clientobj, &a1) == 0);
 
+  if (s_trace_clientobj)
+  {
+    VG_(message)(Vg_UserMsg, "Adding client object 0x%lx of type %d", a1, t);
+  }
+
   p = VG_(OSetGen_AllocNode)(s_clientobj, sizeof(*p));
   VG_(memset)(p, 0, sizeof(*p));
   p->any.a1   = a1;
@@ -116,10 +130,20 @@
   return p;
 }
 
-Bool drd_clientobj_remove(const Addr addr, const ObjType t)
+Bool clientobj_remove(const Addr addr, const ObjType t)
 {
   DrdClientobj* p;
 
+  if (s_trace_clientobj)
+  {
+    VG_(message)(Vg_UserMsg, "Removing client object 0x%lx of type %d",
+                 addr, t);
+#if 0
+    VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
+                               VG_(clo_backtrace_size));
+#endif
+  }
+
   p = VG_(OSetGen_Lookup)(s_clientobj, &addr);
   tl_assert(p->any.type == t);
   p = VG_(OSetGen_Remove)(s_clientobj, &addr);
@@ -135,7 +159,7 @@
   return False;
 }
 
-void drd_clientobj_stop_using_mem(const Addr a1, const Addr a2)
+void clientobj_stop_using_mem(const Addr a1, const Addr a2)
 {
   Addr removed_at;
   DrdClientobj* p;
@@ -149,7 +173,7 @@
         || (a1 < p->any.a2 && p->any.a2 <= a2))
     {
       removed_at = p->any.a1;
-      drd_clientobj_remove(p->any.a1, p->any.type);
+      clientobj_remove(p->any.a1, p->any.type);
       /* The above call removes an element from the oset and hence */
       /* invalidates the iterator. Set the iterator back.          */
       VG_(OSetGen_ResetIter)(s_clientobj);
@@ -164,12 +188,12 @@
   }
 }
 
-void drd_clientobj_resetiter(void)
+void clientobj_resetiter(void)
 {
   VG_(OSetGen_ResetIter)(s_clientobj);
 }
 
-DrdClientobj* drd_clientobj_next(const ObjType t)
+DrdClientobj* clientobj_next(const ObjType t)
 {
   DrdClientobj* p;
   while ((p = VG_(OSetGen_Next)(s_clientobj)) != 0 && p->any.type != t)
diff --git a/exp-drd/drd_clientobj.h b/exp-drd/drd_clientobj.h
index 82bb8dc..831d543 100644
--- a/exp-drd/drd_clientobj.h
+++ b/exp-drd/drd_clientobj.h
@@ -116,14 +116,15 @@
 
 // Function declarations.
 
-void drd_clientobj_init(void);
-void drd_clientobj_cleanup(void);
-DrdClientobj* drd_clientobj_get(const Addr addr, const ObjType t);
-Bool drd_clientobj_present(const Addr a1, const Addr a2);
-DrdClientobj* drd_clientobj_add(const Addr a1, const Addr a2, const ObjType t);
-Bool drd_clientobj_remove(const Addr addr, const ObjType t);
-void drd_clientobj_stop_using_mem(const Addr a1, const Addr a2);
-void drd_clientobj_resetiter(void);
-DrdClientobj* drd_clientobj_next(const ObjType t);
+void clientobj_set_trace(const Bool trace);
+void clientobj_init(void);
+void clientobj_cleanup(void);
+DrdClientobj* clientobj_get(const Addr addr, const ObjType t);
+Bool clientobj_present(const Addr a1, const Addr a2);
+DrdClientobj* clientobj_add(const Addr a1, const Addr a2, const ObjType t);
+Bool clientobj_remove(const Addr addr, const ObjType t);
+void clientobj_stop_using_mem(const Addr a1, const Addr a2);
+void clientobj_resetiter(void);
+DrdClientobj* clientobj_next(const ObjType t);
 
 #endif /* __DRD_CLIENTOBJ_H */
diff --git a/exp-drd/drd_clientreq.c b/exp-drd/drd_clientreq.c
index 07d101b..3eb9598 100644
--- a/exp-drd/drd_clientreq.c
+++ b/exp-drd/drd_clientreq.c
@@ -149,12 +149,12 @@
       drd_spin_init_or_unlock(arg[1], arg[2]);
       break;
 
-   case VG_USERREQ__POST_PTHREAD_COND_INIT:
-      drd_post_cond_init(arg[1], arg[2]);
+   case VG_USERREQ__PRE_PTHREAD_COND_INIT:
+      drd_pre_cond_init(arg[1], arg[2]);
       break;
 
-   case VG_USERREQ__PRE_PTHREAD_COND_DESTROY:
-      drd_pre_cond_destroy(arg[1]);
+   case VG_USERREQ__POST_PTHREAD_COND_DESTROY:
+      drd_post_cond_destroy(arg[1]);
       break;
 
    case VG_USERREQ__PRE_PTHREAD_COND_WAIT:
diff --git a/exp-drd/drd_clientreq.h b/exp-drd/drd_clientreq.h
index daed51f..7489711 100644
--- a/exp-drd/drd_clientreq.h
+++ b/exp-drd/drd_clientreq.h
@@ -63,10 +63,10 @@
 
 
   /* to notify the drd tool of a pthread_cond_init call. */
-  VG_USERREQ__POST_PTHREAD_COND_INIT,
+  VG_USERREQ__PRE_PTHREAD_COND_INIT,
   /* args: Addr */
   /* to notify the drd tool of a pthread_cond_destroy call. */
-  VG_USERREQ__PRE_PTHREAD_COND_DESTROY,
+  VG_USERREQ__POST_PTHREAD_COND_DESTROY,
   /* 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 */
diff --git a/exp-drd/drd_cond.c b/exp-drd/drd_cond.c
index 4e2dbd0..3a1228f 100644
--- a/exp-drd/drd_cond.c
+++ b/exp-drd/drd_cond.c
@@ -68,7 +68,7 @@
 }
 
 /** Free the memory that was allocated by cond_initialize(). Called by
- *  drd_clientobj_remove().
+ *  clientobj_remove().
  */
 static void cond_cleanup(struct cond_info* p)
 {
@@ -76,7 +76,7 @@
   if (p->mutex)
   {
     struct mutex_info* q;
-    q = &drd_clientobj_get(p->mutex, ClientMutex)->mutex;
+    q = &clientobj_get(p->mutex, ClientMutex)->mutex;
     tl_assert(q);
     {
       CondDestrErrInfo cde = { p->a1, q->a1, q->owner };
@@ -96,24 +96,26 @@
   struct cond_info *p;
 
   tl_assert(offsetof(DrdClientobj, cond) == 0);
-  p = &drd_clientobj_get(cond, ClientCondvar)->cond;
+  p = &clientobj_get(cond, ClientCondvar)->cond;
   if (p == 0)
   {
-    p = &drd_clientobj_add(cond, cond + size, ClientCondvar)->cond;
+    p = &clientobj_add(cond, cond + size, ClientCondvar)->cond;
     cond_initialize(p, cond, size);
   }
   return p;
 }
 
-struct cond_info* cond_get(const Addr cond)
+static struct cond_info* cond_get(const Addr cond)
 {
   tl_assert(offsetof(DrdClientobj, cond) == 0);
-  return &drd_clientobj_get(cond, ClientCondvar)->cond;
+  return &clientobj_get(cond, ClientCondvar)->cond;
 }
 
 /** Called before pthread_cond_init(). */
-void cond_init(const Addr cond, const SizeT size)
+void cond_pre_init(const Addr cond, const SizeT size)
 {
+  struct cond_info* p;
+
   if (s_trace_cond)
   {
     VG_(message)(Vg_UserMsg,
@@ -122,27 +124,62 @@
                  thread_get_running_tid(),
                  cond);
   }
-  tl_assert(cond_get(cond) == 0);
+
   tl_assert(size > 0);
-  cond_get_or_allocate(cond, size);
+
+  p = cond_get(cond);
+
+  if (p)
+  {
+    CondErrInfo cei = { .cond = cond };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            CondErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "initialized twice",
+                            &cei);
+  }
+
+  p = cond_get_or_allocate(cond, size);
 }
 
 /** Called after pthread_cond_destroy(). */
-void cond_destroy(struct cond_info* const p)
+void cond_post_destroy(const Addr cond)
 {
+  struct cond_info* p;
+
   if (s_trace_cond)
   {
     VG_(message)(Vg_UserMsg,
                  "[%d/%d] cond_destroy 0x%lx",
                  VG_(get_running_tid)(),
                  thread_get_running_tid(),
-                 p->a1);
+                 cond);
   }
 
-  // TO DO: print a proper error message if waiter_count != 0.
-  tl_assert(p->waiter_count == 0);
+  p = cond_get(cond);
+  if (p == 0)
+  {
+    CondErrInfo cei = { .cond = cond };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            CondErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "not a condition variable",
+                            &cei);
+    return;
+  }
 
-  drd_clientobj_remove(p->a1, ClientCondvar);
+  if (p->waiter_count != 0)
+  {
+    CondErrInfo cei = { .cond = cond };
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            CondErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "destruction of condition variable being waited"
+                            " upon",
+                            &cei);
+  }
+
+  clientobj_remove(p->a1, ClientCondvar);
 }
 
 /** Called before pthread_cond_wait(). */
diff --git a/exp-drd/drd_cond.h b/exp-drd/drd_cond.h
index fafaa31..03db2a5 100644
--- a/exp-drd/drd_cond.h
+++ b/exp-drd/drd_cond.h
@@ -39,9 +39,8 @@
 
 
 void cond_set_trace(const Bool trace_cond);
-void cond_init(const Addr cond, const SizeT size);
-void cond_destroy(struct cond_info* const p);
-struct cond_info* cond_get(const Addr mutex);
+void cond_pre_init(const Addr cond, const SizeT size);
+void cond_post_destroy(const Addr cond);
 int cond_pre_wait(const Addr cond, const SizeT cond_size, const Addr mutex);
 int cond_post_wait(const Addr cond);
 void cond_pre_signal(const Addr cond);
diff --git a/exp-drd/drd_intercepts.c b/exp-drd/drd_intercepts.c
index 4c54f5d..06e5bdc 100644
--- a/exp-drd/drd_intercepts.c
+++ b/exp-drd/drd_intercepts.c
@@ -395,9 +395,9 @@
    int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   CALL_FN_W_WW(ret, fn, cond, attr);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_INIT,
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_INIT,
                               cond, sizeof(*cond), 0, 0, 0);
+   CALL_FN_W_WW(ret, fn, cond, attr);
    return ret;
 }
 
@@ -409,9 +409,9 @@
    int res;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_DESTROY,
-                              cond, 0, 0, 0, 0);
    CALL_FN_W_W(ret, fn, cond);
+   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_DESTROY,
+                              cond, 0, 0, 0, 0);
    return ret;
 }
 
diff --git a/exp-drd/drd_main.c b/exp-drd/drd_main.c
index 67b583f..2f929e2 100644
--- a/exp-drd/drd_main.c
+++ b/exp-drd/drd_main.c
@@ -47,7 +47,7 @@
 #include "pub_tool_libcproc.h"
 #include "pub_tool_machine.h"
 #include "pub_tool_options.h"     // command line options
-#include "pub_tool_threadstate.h" // VG_(get_running_tid)
+#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
 #include "pub_tool_tooliface.h"
 
 
@@ -77,6 +77,7 @@
 static Bool drd_process_cmd_line_option(Char* arg)
 {
    Bool trace_barrier     = False;
+   Bool trace_clientobj   = False;
    Bool trace_cond        = False;
    Bool trace_csw         = False;
    Bool trace_danger_set  = False;
@@ -88,6 +89,7 @@
 
    VG_BOOL_CLO     (arg, "--drd-stats",         drd_print_stats)
    else VG_BOOL_CLO(arg, "--trace-barrier",     trace_barrier)
+   else VG_BOOL_CLO(arg, "--trace-clientobj",   trace_clientobj)
    else VG_BOOL_CLO(arg, "--trace-cond",        trace_cond)
    else VG_BOOL_CLO(arg, "--trace-csw",         trace_csw)
    else VG_BOOL_CLO(arg, "--trace-danger-set",  trace_danger_set)
@@ -107,6 +109,8 @@
    }
    if (trace_barrier)
       barrier_set_trace(trace_barrier);
+   if (trace_clientobj)
+      clientobj_set_trace(trace_clientobj);
    if (trace_cond)
       cond_set_trace(trace_cond);
    if (trace_csw)
@@ -306,7 +310,7 @@
                                  VG_(clo_backtrace_size));
    }
    thread_stop_using_mem(a1, a2);
-   drd_clientobj_stop_using_mem(a1, a2);
+   clientobj_stop_using_mem(a1, a2);
    drd_suppression_stop_using_mem(a1, a2);
 }
 
@@ -473,38 +477,14 @@
    mutex_unlock(mutex, mutex_type);
 }
 
-void drd_post_cond_init(Addr cond, SizeT s)
+void drd_pre_cond_init(Addr cond, SizeT s)
 {
-   if (cond_get(cond))
-   {
-      CondErrInfo cei = { .cond = cond };
-      VG_(maybe_record_error)(VG_(get_running_tid)(),
-                              CondErr,
-                              VG_(get_IP)(VG_(get_running_tid)()),
-                              "initialized twice",
-                              &cei);
-   }
-   cond_init(cond, s);
+   cond_pre_init(cond, s);
 }
 
-void drd_pre_cond_destroy(Addr cond)
+void drd_post_cond_destroy(Addr cond)
 {
-   struct cond_info* cond_p;
-
-   cond_p = cond_get(cond);
-   if (cond_p)
-   {
-      cond_destroy(cond_p);
-   }
-   else
-   {
-      CondErrInfo cei = { .cond = cond };
-      VG_(maybe_record_error)(VG_(get_running_tid)(),
-                              CondErr,
-                              VG_(get_IP)(VG_(get_running_tid)()),
-                              "destroy requested but not initialized",
-                              &cei);
-   }
+   cond_post_destroy(cond);
 }
 
 void drd_semaphore_init(const Addr semaphore, const SizeT size,
@@ -515,14 +495,7 @@
 
 void drd_semaphore_destroy(const Addr semaphore)
 {
-   struct semaphore_info* p;
-
-   p = semaphore_get(semaphore);
-   tl_assert(p);
-   if (p)
-   {
-      semaphore_destroy(p);
-   }
+   semaphore_destroy(semaphore);
 }
 
 void drd_semaphore_pre_wait(const DrdThreadId tid, const Addr semaphore,
@@ -557,13 +530,7 @@
 
 void drd_barrier_destroy(const Addr barrier)
 {
-   struct barrier_info* p;
-
-   p = barrier_get(barrier);
-   if (p)
-   {
-      barrier_destroy(p);
-   }
+   barrier_destroy(barrier);
 }
 
 void drd_barrier_pre_wait(const DrdThreadId tid, const Addr barrier)
@@ -859,7 +826,7 @@
 
    drd_suppression_init();
 
-   drd_clientobj_init();
+   clientobj_init();
 }
 
 
diff --git a/exp-drd/drd_malloc_wrappers.c b/exp-drd/drd_malloc_wrappers.c
index 55ae703..dcfde41 100644
--- a/exp-drd/drd_malloc_wrappers.c
+++ b/exp-drd/drd_malloc_wrappers.c
@@ -143,7 +143,7 @@
    }
    else
    {
-      s_stop_using_mem_callback(mc->data, mc->data + mc->size);
+      s_stop_using_mem_callback(mc->data, mc->size);
       VG_(free)(mc);
    }
 }
@@ -184,7 +184,7 @@
    else if (old_size > new_size)
    {
       /* new size is smaller */
-      s_stop_using_mem_callback(mc->data + new_size, mc->data + old_size);
+      s_stop_using_mem_callback(mc->data + new_size, old_size);
       mc->size = new_size;
       mc->where = VG_(record_ExeContext)(tid, 0);
       p_new = p_old;
@@ -202,7 +202,7 @@
          VG_(memcpy)((void*)a_new, p_old, mc->size);
 
          /* Free old memory */
-         s_stop_using_mem_callback(mc->data, mc->data + mc->size);
+         s_stop_using_mem_callback(mc->data, mc->size);
          VG_(free)(mc);
 
          // Allocate a new chunk.
diff --git a/exp-drd/drd_mutex.c b/exp-drd/drd_mutex.c
index 568bf4d..e99b4bb 100644
--- a/exp-drd/drd_mutex.c
+++ b/exp-drd/drd_mutex.c
@@ -38,7 +38,6 @@
 
 static void mutex_cleanup(struct mutex_info* p);
 static Bool mutex_is_locked(struct mutex_info* const p);
-static void mutex_destroy(struct mutex_info* const p);
 
 
 // Local variables.
@@ -108,7 +107,7 @@
   struct mutex_info* p;
 
   tl_assert(offsetof(DrdClientobj, mutex) == 0);
-  p = &drd_clientobj_get(mutex, ClientMutex)->mutex;
+  p = &clientobj_get(mutex, ClientMutex)->mutex;
   if (p)
   {
     tl_assert(p->mutex_type == mutex_type);
@@ -116,7 +115,7 @@
     return p;
   }
 
-  if (drd_clientobj_present(mutex, mutex + size))
+  if (clientobj_present(mutex, mutex + size))
   {
      GenericErrInfo GEI;
      VG_(maybe_record_error)(VG_(get_running_tid)(),
@@ -127,7 +126,7 @@
      return 0;
   }
 
-  p = &drd_clientobj_add(mutex, mutex + size, ClientMutex)->mutex;
+  p = &clientobj_add(mutex, mutex + size, ClientMutex)->mutex;
   mutex_initialize(p, mutex, size, mutex_type);
   return p;
 }
@@ -135,7 +134,7 @@
 struct mutex_info* mutex_get(const Addr mutex)
 {
   tl_assert(offsetof(DrdClientobj, mutex) == 0);
-  return &drd_clientobj_get(mutex, ClientMutex)->mutex;
+  return &clientobj_get(mutex, ClientMutex)->mutex;
 }
 
 struct mutex_info*
@@ -171,22 +170,24 @@
   return mutex_p;
 }
 
-static void mutex_destroy(struct mutex_info* const p)
-{
-  drd_clientobj_remove(p->a1, ClientMutex);
-}
-
 /** Called after pthread_mutex_destroy(). */
 void mutex_post_destroy(const Addr mutex)
 {
-   struct mutex_info* p;
+  struct mutex_info* p;
 
-   p = mutex_get(mutex);
-   tl_assert(p);
-   if (p)
-   {
-      mutex_destroy(p);
-   }
+  p = mutex_get(mutex);
+  if (p == 0)
+  {
+    GenericErrInfo GEI;
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            GenericErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Not a mutex",
+                            &GEI);
+    return;
+  }
+
+  clientobj_remove(mutex, ClientMutex);
 }
 
 /** Called before pthread_mutex_lock() is invoked. If a data structure for
@@ -466,8 +467,8 @@
 {
   struct mutex_info* p;
 
-  drd_clientobj_resetiter();
-  for ( ; (p = &drd_clientobj_next(ClientMutex)->mutex) != 0; )
+  clientobj_resetiter();
+  for ( ; (p = &clientobj_next(ClientMutex)->mutex) != 0; )
   {
     if (p->owner == tid && p->recursion_count > 0)
     {
diff --git a/exp-drd/drd_semaphore.c b/exp-drd/drd_semaphore.c
index 513dcd1..48b6f91 100644
--- a/exp-drd/drd_semaphore.c
+++ b/exp-drd/drd_semaphore.c
@@ -72,7 +72,7 @@
 }
 
 /** Free the memory that was allocated by semaphore_initialize(). Called by
- *  drd_clientobj_remove().
+ *  clientobj_remove().
  */
 static void semaphore_cleanup(struct semaphore_info* p)
 {
@@ -96,21 +96,21 @@
   struct semaphore_info *p;
 
   tl_assert(offsetof(DrdClientobj, semaphore) == 0);
-  p = &drd_clientobj_get(semaphore, ClientSemaphore)->semaphore;
+  p = &clientobj_get(semaphore, ClientSemaphore)->semaphore;
   if (p == 0)
   {
     tl_assert(offsetof(DrdClientobj, semaphore) == 0);
-    p = &drd_clientobj_add(semaphore, semaphore + size,
+    p = &clientobj_add(semaphore, semaphore + size,
                            ClientSemaphore)->semaphore;
     semaphore_initialize(p, semaphore, size, 0);
   }
   return p;
 }
 
-struct semaphore_info* semaphore_get(const Addr semaphore)
+static struct semaphore_info* semaphore_get(const Addr semaphore)
 {
   tl_assert(offsetof(DrdClientobj, semaphore) == 0);
-  return &drd_clientobj_get(semaphore, ClientSemaphore)->semaphore;
+  return &clientobj_get(semaphore, ClientSemaphore)->semaphore;
 }
 
 /** Called before sem_init(). */
@@ -134,9 +134,9 @@
 }
 
 /** Called after sem_destroy(). */
-void semaphore_destroy(struct semaphore_info* const p)
+void semaphore_destroy(const Addr semaphore)
 {
-  tl_assert(p);
+  struct semaphore_info* p;
 
   if (s_trace_semaphore)
   {
@@ -144,10 +144,23 @@
                  "[%d/%d] semaphore_destroy 0x%lx",
                  VG_(get_running_tid)(),
                  thread_get_running_tid(),
-                 p->a1);
+                 semaphore);
   }
 
-  drd_clientobj_remove(p->a1, ClientSemaphore);
+  p = semaphore_get(semaphore);
+
+  if (p == 0)
+  {
+    GenericErrInfo GEI;
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            GenericErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Not a semaphore",
+                            &GEI);
+    return;
+  }
+
+  clientobj_remove(semaphore, ClientSemaphore);
 }
 
 /** Called before sem_wait(). */
diff --git a/exp-drd/drd_semaphore.h b/exp-drd/drd_semaphore.h
index 9a49bde..0c151e8 100644
--- a/exp-drd/drd_semaphore.h
+++ b/exp-drd/drd_semaphore.h
@@ -41,8 +41,7 @@
 void semaphore_set_trace(const Bool trace_semaphore);
 struct semaphore_info* semaphore_init(const Addr semaphore, const SizeT size,
                                       const Word pshared, const UWord value);
-void semaphore_destroy(struct semaphore_info* const p);
-struct semaphore_info* semaphore_get(const Addr semaphore);
+void semaphore_destroy(const Addr semaphore);
 void semaphore_pre_wait(const Addr semaphore, const SizeT size);
 void semaphore_post_wait(const DrdThreadId tid, const Addr semaphore,
                          const Bool waited);
diff --git a/exp-drd/drd_track.h b/exp-drd/drd_track.h
index 1c71c84..c0d81e4 100644
--- a/exp-drd/drd_track.h
+++ b/exp-drd/drd_track.h
@@ -34,8 +34,8 @@
 void drd_pre_mutex_unlock(const DrdThreadId tid, const Addr mutex,
                           const MutexT mutex_type);
 
-void drd_post_cond_init(Addr cond, SizeT s);
-void drd_pre_cond_destroy(Addr cond);
+void drd_pre_cond_init(Addr cond, SizeT s);
+void drd_post_cond_destroy(Addr cond);
 
 void drd_semaphore_init(const Addr semaphore, const SizeT size,
                         const Word pshared, const Word value);