Author: bart
Date: 2008-03-03 20:31:58 +0000 (Mon, 03 Mar 2008)
New Revision: 7549

Log:
Added new command-line option --trace-rwlock. Added regression test 
exp-drd/tests/rwlock_race. Updated to do list. Fixed bug in vc_min(), the 
function that computes the elementwise minimum of two vector clocks. Fixed bug 
in thread_update_danger_set(). Fixed recently introduced bug in mutex code with 
regard to vector clock combining.

Added:
   trunk/exp-drd/tests/rwlock_race.c
   trunk/exp-drd/tests/rwlock_race.stderr.exp
   trunk/exp-drd/tests/rwlock_race.vgtest
Modified:
   trunk/exp-drd/TODO.txt
   trunk/exp-drd/drd_clientreq.c
   trunk/exp-drd/drd_clientreq.h
   trunk/exp-drd/drd_intercepts.c
   trunk/exp-drd/drd_main.c
   trunk/exp-drd/drd_mutex.c
   trunk/exp-drd/drd_rwlock.c
   trunk/exp-drd/drd_thread.c
   trunk/exp-drd/drd_track.h
   trunk/exp-drd/drd_vc.c
   trunk/exp-drd/tests/Makefile.am
   trunk/exp-drd/tests/tc06_two_races.stderr.exp
   trunk/exp-drd/tests/tc21_pthonce.stderr.exp
   trunk/glibc-2.X-drd.supp


Modified: trunk/exp-drd/TODO.txt
===================================================================
--- trunk/exp-drd/TODO.txt      2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/TODO.txt      2008-03-03 20:31:58 UTC (rev 7549)
@@ -12,6 +12,11 @@
   without triggering Valgrind's redirection mechanism.
 - Discuss on the Valgrind mailing list the modificaiton of tests/vg_regtest
   such that it ignores files ending in ~ or #.
+- Continue the discussion on the Valgrind mailing list about docbook and
+  'make dist'.
+- Continue the discussion on the Valgrind mailing list about -Wformat.
+- Explain on the Valgrind mailing list the difference between a bus lock
+  and acquire / release labels.
 - Find out why a race is reported on std::string::string(std::string const&)
   (stc test case 16).
 - Add support for objects that are shared over threads and that use reference
@@ -27,8 +32,9 @@
 - Performance testing and tuning.
 - testing on PPC and AIX (current implementation is only tested on X86 and
   AMD64).
-- [AMD64] Find out why removing 'write(1, "", 0)' in drd_intercepts.c triggers
-  a crash on AMD64. Is this an exp-drd or a VEX bug ?
+- Find out why there are sometimes races reported on exp-drd/test/matinv.
+- [Fedora 8] Find out why pth_broadcast sometimes hangs on Fedora 8. Is this an
+  exp-drd, pth_broadcast, kernel or glibc bug ?
 - On x86 and amd64 platforms, add support for implicit locking arising from
   the use of the LOCK instruction prefix.
 - Convert the array in drd_thread.c with thread information into an OSet.
@@ -65,5 +71,3 @@
   (works fine on i386). This is a bug in Valgrind's debug info reader
   -- VG_(find_seginfo)() returns NULL for BSS symbols on x86_64. Not yet in
   the KDE bug tracking system.
-- No error message is printed for tc20_verifywrap when a locked mutex is
-  deallocated (mutex was allocated on the stack).

Modified: trunk/exp-drd/drd_clientreq.c
===================================================================
--- trunk/exp-drd/drd_clientreq.c       2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_clientreq.c       2008-03-03 20:31:58 UTC (rev 7549)
@@ -111,6 +111,10 @@
       thread_new_segment(PtThreadIdToDrdThreadId(arg[1]));
       break;
 
+   case VG_USERREQ__DRD_TRACE_ADDR:
+      drd_trace_addr(arg[1]);
+      break;
+
    case VG_USERREQ__SET_PTHREADID:
       thread_set_pthreadid(thread_get_running_tid(), arg[1]);
       break;

Modified: trunk/exp-drd/drd_clientreq.h
===================================================================
--- trunk/exp-drd/drd_clientreq.h       2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_clientreq.h       2008-03-03 20:31:58 UTC (rev 7549)
@@ -28,6 +28,9 @@
   /* To ask the drd tool to start a new segment in the specified thread. */
   VG_USERREQ__DRD_START_NEW_SEGMENT,
   /* args: POSIX thread ID. */
+  /* To ask the drd tool to trace all accesses to the specified address. */
+  VG_USERREQ__DRD_TRACE_ADDR,
+  /* args: Addr. */
 
   /* Tell the core the pthread_t of the running thread */
   VG_USERREQ__SET_PTHREADID,

Modified: trunk/exp-drd/drd_intercepts.c
===================================================================
--- trunk/exp-drd/drd_intercepts.c      2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_intercepts.c      2008-03-03 20:31:58 UTC (rev 7549)
@@ -339,12 +339,6 @@
    VALGRIND_GET_ORIG_FN(fn);
    VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
                               mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
-#if 1
-   // The only purpose of the system call below is to make drd work on AMD64
-   // systems. Without this system call, clients crash (SIGSEGV) in
-   // std::locale::locale().
-   write(1, "", 0);
-#endif
    CALL_FN_W_W(ret, fn, mutex);
    VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
                               mutex, ret == 0, 0, 0, 0);

Modified: trunk/exp-drd/drd_main.c
===================================================================
--- trunk/exp-drd/drd_main.c    2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_main.c    2008-03-03 20:31:58 UTC (rev 7549)
@@ -30,6 +30,7 @@
 #include "drd_error.h"
 #include "drd_malloc_wrappers.h"
 #include "drd_mutex.h"
+#include "drd_rwlock.h"
 #include "drd_segment.h"
 #include "drd_semaphore.h"
 #include "drd_suppression.h"
@@ -82,6 +83,7 @@
    Bool trace_csw         = False;
    Bool trace_danger_set  = False;
    Bool trace_mutex       = False;
+   Bool trace_rwlock      = False;
    Bool trace_segment     = False;
    Bool trace_semaphore   = False;
    Bool trace_suppression = False;
@@ -96,6 +98,7 @@
    else VG_BOOL_CLO(arg, "--trace-fork-join",   drd_trace_fork_join)
    else VG_BOOL_CLO(arg, "--trace-mem",         drd_trace_mem)
    else VG_BOOL_CLO(arg, "--trace-mutex",       trace_mutex)
+   else VG_BOOL_CLO(arg, "--trace-rwlock",      trace_rwlock)
    else VG_BOOL_CLO(arg, "--trace-segment",     trace_segment)
    else VG_BOOL_CLO(arg, "--trace-semaphore",   trace_semaphore)
    else VG_BOOL_CLO(arg, "--trace-suppression", trace_suppression)
@@ -119,6 +122,8 @@
       thread_trace_danger_set(trace_danger_set);
    if (trace_mutex)
       mutex_set_trace(trace_mutex);
+   if (trace_rwlock)
+      rwlock_set_trace(trace_rwlock);
    if (trace_segment)
       sg_set_trace(trace_segment);
    if (trace_semaphore)
@@ -160,12 +165,15 @@
 #if 1
    if (drd_trace_mem || (addr == drd_trace_address))
    {
-      VG_(message)(Vg_UserMsg, "load  0x%lx size %ld %s (vg %d / drd %d)",
+      char vc[80];
+      vc_snprint(vc, sizeof(vc), thread_get_vc(thread_get_running_tid()));
+      VG_(message)(Vg_UserMsg, "load  0x%lx size %ld %s (vg %d / drd %d / vc 
%s)",
                    addr,
                    size,
                    thread_get_name(thread_get_running_tid()),
                    VG_(get_running_tid)(),
-                   thread_get_running_tid());
+                   thread_get_running_tid(),
+                   vc);
       VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
                                  VG_(clo_backtrace_size));
       tl_assert(DrdThreadIdToVgThreadId(thread_get_running_tid())
@@ -200,13 +208,16 @@
 #if 1
    if (drd_trace_mem || (addr == drd_trace_address))
    {
-      VG_(message)(Vg_UserMsg, "store 0x%lx size %ld %s (vg %d / drd %d / off 
%d)",
+      char vc[80];
+      vc_snprint(vc, sizeof(vc), thread_get_vc(thread_get_running_tid()));
+      VG_(message)(Vg_UserMsg, "store 0x%lx size %ld %s (vg %d / drd %d / off 
%d / vc %s)",
                    addr,
                    size,
                    thread_get_name(thread_get_running_tid()),
                    VG_(get_running_tid)(),
                    thread_get_running_tid(),
-                   addr - thread_get_stack_min(thread_get_running_tid()));
+                   addr - thread_get_stack_min(thread_get_running_tid()),
+                   vc);
       VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
                                  VG_(clo_backtrace_size));
       tl_assert(DrdThreadIdToVgThreadId(thread_get_running_tid())
@@ -420,6 +431,11 @@
    barrier_thread_delete(drd_joinee);
 }
 
+void drd_trace_addr(const Addr addr)
+{
+   drd_trace_address = addr;
+}
+
 /* Called after a thread has performed its last memory access. */
 static void drd_thread_finished(ThreadId tid)
 {

Modified: trunk/exp-drd/drd_mutex.c
===================================================================
--- trunk/exp-drd/drd_mutex.c   2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_mutex.c   2008-03-03 20:31:58 UTC (rev 7549)
@@ -29,6 +29,7 @@
 #include "priv_drd_clientreq.h"
 #include "pub_tool_errormgr.h"    // VG_(maybe_record_error)()
 #include "pub_tool_libcassert.h"  // tl_assert()
+#include "pub_tool_libcbase.h"    // VG_(strlen)
 #include "pub_tool_libcprint.h"   // VG_(message)()
 #include "pub_tool_machine.h"     // VG_(get_IP)()
 #include "pub_tool_threadstate.h" // VG_(get_running_tid)()
@@ -117,13 +118,13 @@
 
   if (clientobj_present(mutex, mutex + size))
   {
-     GenericErrInfo GEI;
-     VG_(maybe_record_error)(VG_(get_running_tid)(),
-                             GenericErr,
-                             VG_(get_IP)(VG_(get_running_tid)()),
-                             "Not a mutex",
-                             &GEI);
-     return 0;
+    GenericErrInfo GEI;
+    VG_(maybe_record_error)(VG_(get_running_tid)(),
+                            GenericErr,
+                            VG_(get_IP)(VG_(get_running_tid)()),
+                            "Not a mutex",
+                            &GEI);
+    return 0;
   }
 
   p = &clientobj_add(mutex, mutex + size, ClientMutex)->mutex;
@@ -281,10 +282,16 @@
   }
 
   if (! p || ! took_lock)
-     return;
+    return;
 
   if (p->recursion_count == 0)
   {
+    const DrdThreadId last_owner = p->owner;
+
+    if (last_owner != drd_tid && last_owner != DRD_INVALID_THREADID)
+      thread_combine_vc2(drd_tid, mutex_get_last_vc(mutex));
+    thread_new_segment(drd_tid);
+
     p->owner = drd_tid;
     s_mutex_lock_count++;
   }
@@ -298,15 +305,6 @@
     p->owner = drd_tid;
   }
   p->recursion_count++;
-
-  if (p->recursion_count == 1)
-  {
-     const DrdThreadId last_owner = p->owner;
-
-    if (last_owner != drd_tid && last_owner != DRD_INVALID_THREADID)
-      thread_combine_vc2(drd_tid, mutex_get_last_vc(mutex));
-    thread_new_segment(drd_tid);
-  }
 }
 
 /**
@@ -339,13 +337,13 @@
 
   if (p == 0 || mutex_type == mutex_type_invalid_mutex)
   {
-     GenericErrInfo GEI;
-     VG_(maybe_record_error)(vg_tid,
-                             GenericErr,
-                             VG_(get_IP)(vg_tid),
-                             "Not a mutex",
-                             &GEI);
-     return;
+    GenericErrInfo GEI;
+    VG_(maybe_record_error)(vg_tid,
+                            GenericErr,
+                            VG_(get_IP)(vg_tid),
+                            "Not a mutex",
+                            &GEI);
+    return;
   }
 
   if (p->owner == DRD_INVALID_THREADID)
@@ -356,14 +354,14 @@
                             VG_(get_IP)(vg_tid),
                             "Mutex not locked",
                             &MEI);
-     return;
+    return;
   }
 
   tl_assert(p);
   if (p->mutex_type != mutex_type)
   {
     VG_(message)(Vg_UserMsg, "??? mutex %p: type changed from %d into %d",
-                p->a1, p->mutex_type, mutex_type);
+                 p->a1, p->mutex_type, mutex_type);
   }
   tl_assert(p->mutex_type == mutex_type);
   tl_assert(p->owner != DRD_INVALID_THREADID);
@@ -483,6 +481,6 @@
 
 /*
  * Local variables:
- * c-basic-offset: 3
+ * c-basic-offset: 2
  * End:
  */

Modified: trunk/exp-drd/drd_rwlock.c
===================================================================
--- trunk/exp-drd/drd_rwlock.c  2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_rwlock.c  2008-03-03 20:31:58 UTC (rev 7549)
@@ -39,10 +39,11 @@
 
 struct rwlock_thread_info
 {
-  UWord tid;        // DrdThreadId.
-  UInt  reader_nesting_count;
-  UInt  writer_nesting_count;
+  UWord       tid;        // DrdThreadId.
+  UInt        reader_nesting_count;
+  UInt        writer_nesting_count;
   VectorClock vc;   // Vector clock associated with last unlock by this thread.
+  Bool        last_lock_was_writer_lock;
 };
 
 
@@ -129,6 +130,7 @@
     q->reader_nesting_count = 0;
     q->writer_nesting_count = 0;
     vc_init(&q->vc, 0, 0);
+    q->last_lock_was_writer_lock = False;
     VG_(OSetGen_Insert)(oset, q);
   }
   tl_assert(q);
@@ -136,14 +138,15 @@
 }
 
 static void rwlock_combine_other_vc(struct rwlock_info* const p,
-                                    const DrdThreadId tid)
+                                    const DrdThreadId tid,
+                                    const Bool readers_too)
 {
   struct rwlock_thread_info* q;
 
   VG_(OSetGen_ResetIter)(p->thread_info);
   for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
   {
-    if (q->tid != tid)
+    if (q->tid != tid && (readers_too || q->last_lock_was_writer_lock))
     {
       thread_combine_vc2(tid, &q->vc);
     }
@@ -175,7 +178,7 @@
   if (s_trace_rwlock)
   {
     VG_(message)(Vg_UserMsg,
-                 "[%d/%d] rwlock_destroy   0x%lx",
+                 "[%d/%d] rwlock_destroy     0x%lx",
                  VG_(get_running_tid)(),
                  thread_get_running_tid(),
                  p->a1);
@@ -244,7 +247,7 @@
   if (s_trace_rwlock)
   {
     VG_(message)(Vg_UserMsg,
-                 "[%d/%d] rwlock_init      %s 0x%lx",
+                 "[%d/%d] rwlock_init        0x%lx",
                  VG_(get_running_tid)(),
                  thread_get_running_tid(),
                  rwlock);
@@ -351,7 +354,7 @@
   q = lookup_or_insert_node(p->thread_info, drd_tid);
   if (++q->reader_nesting_count == 1)
   {
-    rwlock_combine_other_vc(p, drd_tid);
+    rwlock_combine_other_vc(p, drd_tid, False);
     thread_new_segment(drd_tid);
   }
 }
@@ -422,8 +425,9 @@
   q = lookup_or_insert_node(p->thread_info, thread_get_running_tid());
   tl_assert(q->writer_nesting_count == 0);
   q->writer_nesting_count++;
+  q->last_lock_was_writer_lock = True;
   tl_assert(q->writer_nesting_count == 1);
-  rwlock_combine_other_vc(p, drd_tid);
+  rwlock_combine_other_vc(p, drd_tid, True);
   thread_new_segment(drd_tid);
 }
 
@@ -447,7 +451,7 @@
   if (s_trace_rwlock && p != 0)
   {
     VG_(message)(Vg_UserMsg,
-                 "[%d/%d] rwlock_unlock    0x%lx",
+                 "[%d/%d] rwlock_unlock      0x%lx",
                  vg_tid,
                  drd_tid,
                  rwlock);
@@ -479,6 +483,7 @@
     /* current vector clock of the thread such that it is available when  */
     /* this rwlock is locked again.                                        */
     vc_assign(&q->vc, vc);
+    q->last_lock_was_writer_lock = False;
 
     thread_new_segment(drd_tid);
   }

Modified: trunk/exp-drd/drd_thread.c
===================================================================
--- trunk/exp-drd/drd_thread.c  2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_thread.c  2008-03-03 20:31:58 UTC (rev 7549)
@@ -582,7 +582,7 @@
 }
 
 /**
- * Discard all segments that have a defined ordered against the latest vector
+ * Discard all segments that have a defined order against the latest vector
  * clock of every thread -- these segments can no longer be involved in a
  * data race.
  */
@@ -875,7 +875,7 @@
       VG_(message)(Vg_DebugMsg, "%s", msg);
    }
 
-   for (p = s_threadinfo[tid].first; p; p = p->next)
+   p = s_threadinfo[tid].last;
    {
       unsigned j;
 
@@ -896,7 +896,8 @@
       {
          if (IsValidDrdThreadId(j))
          {
-            const Segment* const q = s_threadinfo[j].last;
+            const Segment* q;
+            for (q = s_threadinfo[j].last; q; q = q->prev)
             if (j != tid && q != 0
                 && ! vc_lte(&q->vc, &p->vc) && ! vc_lte(&p->vc, &q->vc))
             {

Modified: trunk/exp-drd/drd_track.h
===================================================================
--- trunk/exp-drd/drd_track.h   2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_track.h   2008-03-03 20:31:58 UTC (rev 7549)
@@ -25,6 +25,8 @@
 
 void drd_post_thread_join(DrdThreadId joiner, DrdThreadId joinee);
 
+void drd_trace_addr(const Addr addr);
+
 void drd_pre_mutex_init(Addr mutex, SizeT size, const MutexT mutex_type);
 void drd_post_mutex_destroy(Addr mutex, const MutexT mutex_type);
 void drd_pre_mutex_lock(const Addr mutex, const SizeT size,

Modified: trunk/exp-drd/drd_vc.c
===================================================================
--- trunk/exp-drd/drd_vc.c      2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/drd_vc.c      2008-03-03 20:31:58 UTC (rev 7549)
@@ -134,9 +134,7 @@
   return vc_lte(vc1, vc2) || vc_lte(vc2, vc1);
 }
 
-/**
- * Compute elementwise minimum.
- */
+/** Compute elementwise minimum. */
 void vc_min(VectorClock* const result,
             const VectorClock* const rhs)
 {
@@ -148,7 +146,7 @@
   tl_assert(result);
   tl_assert(rhs);
 
-  // First count the number of shared thread id's.
+  /* First count the number of shared thread ID's. */
   j = 0;
   shared = 0;
   for (i = 0; i < result->size; i++)
@@ -169,14 +167,18 @@
 
   vc_check(result);
 
-  // Next, combine both vector clocks into one.
+  /* Next, combine both vector clocks into one. */
   i = 0;
   for (j = 0; j < rhs->size; j++)
   {
     vc_check(result);
 
     while (i < result->size && result->vc[i].threadid < rhs->vc[j].threadid)
+    {
+      /* Thread ID is missing in second vector clock. Clear the count. */
+      result->vc[i].count = 0;
       i++;
+    }
     if (i >= result->size)
     {
       result->size++;
@@ -185,17 +187,12 @@
     }
     else if (result->vc[i].threadid > rhs->vc[j].threadid)
     {
-      unsigned k;
-      for (k = result->size; k > i; k--)
-      {
-        result->vc[k] = result->vc[k - 1];
-      }
-      result->size++;
-      result->vc[i] = rhs->vc[j];
-      vc_check(result);
+      /* Thread ID is missing in first vector clock. Leave out. */
     }
     else
     {
+      /* The thread ID is present in both vector clocks. Compute the minimum */
+      /* of vc[i].count and vc[j].count. */
       tl_assert(result->vc[i].threadid == rhs->vc[j].threadid);
       if (rhs->vc[j].count < result->vc[i].count)
       {
@@ -205,7 +202,6 @@
     }
   }
   vc_check(result);
-  tl_assert(result->size == new_size);
 }
 
 /**

Modified: trunk/exp-drd/tests/Makefile.am
===================================================================
--- trunk/exp-drd/tests/Makefile.am     2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/exp-drd/tests/Makefile.am     2008-03-03 20:31:58 UTC (rev 7549)
@@ -48,6 +48,7 @@
        pth_detached2.vgtest                                    \
        pth_detached2.stdout.exp pth_detached2.stderr.exp       \
        recursive_mutex.vgtest recursive_mutex.stderr.exp       \
+       rwlock_race.vgtest rwlock_race.stderr.exp               \
        sem_as_mutex.vgtest  sem_as_mutex.stderr.exp            \
        sem_as_mutex2.vgtest sem_as_mutex2.stderr.exp           \
        sigalrm.vgtest                                          \
@@ -121,8 +122,9 @@
   pth_cond_race       \
   pth_create_chain    \
   pth_detached        \
+  recursive_mutex     \
+  rwlock_race         \
   sem_as_mutex        \
-  recursive_mutex     \
   sigalrm             \
   tc01_simple_race    \
   tc02_simple_tls     \
@@ -194,6 +196,9 @@
 recursive_mutex_SOURCES     = recursive_mutex.c
 recursive_mutex_LDADD       = -lpthread
 
+rwlock_race_SOURCES         = rwlock_race.c
+rwlock_race_LDADD           = -lpthread
+
 sem_as_mutex_SOURCES        = sem_as_mutex.c
 sem_as_mutex_LDADD          = -lpthread
 

Added: trunk/exp-drd/tests/rwlock_race.c
===================================================================
--- trunk/exp-drd/tests/rwlock_race.c                           (rev 0)
+++ trunk/exp-drd/tests/rwlock_race.c   2008-03-03 20:31:58 UTC (rev 7549)
@@ -0,0 +1,48 @@
+/** Cause a race inside code protected by a reader lock.
+ */
+
+
+/* Needed for older glibc's (2.3 and older, at least) who don't
+   otherwise "know" about pthread_rwlock_anything or about
+   PTHREAD_MUTEX_RECURSIVE (amongst things). */
+
+#define _GNU_SOURCE 1
+
+#include <stdio.h>
+#include <pthread.h>
+#include "../drd_clientreq.h"
+
+
+static pthread_rwlock_t s_rwlock;
+static int s_racy;
+
+static void* thread(void* arg)
+{
+  pthread_rwlock_rdlock(&s_rwlock);
+  s_racy++;
+  pthread_rwlock_unlock(&s_rwlock);
+  return 0;
+}
+
+int main(int argc, char** argv)
+{
+  pthread_t thread1;
+  pthread_t thread2;
+
+#if 0
+  int res;
+  VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_TRACE_ADDR,
+                             &s_racy, 0, 0, 0, 0);
+#endif
+
+  pthread_rwlock_init(&s_rwlock, 0);
+  pthread_create(&thread1, 0, thread, 0);
+  pthread_create(&thread2, 0, thread, 0);
+  pthread_join(thread1, 0);
+  pthread_join(thread2, 0);
+  pthread_rwlock_destroy(&s_rwlock);
+
+  fprintf(stderr, "Result: %d\n", s_racy);
+
+  return 0;
+}

Added: trunk/exp-drd/tests/rwlock_race.stderr.exp
===================================================================
--- trunk/exp-drd/tests/rwlock_race.stderr.exp                          (rev 0)
+++ trunk/exp-drd/tests/rwlock_race.stderr.exp  2008-03-03 20:31:58 UTC (rev 
7549)
@@ -0,0 +1,26 @@
+
+Thread 2:
+Conflicting load by thread 2 at 0x........ size 4
+   at 0x........: thread (rwlock_race.c:?)
+   by 0x........: vg_thread_wrapper (drd_intercepts.c:?)
+   by 0x........: start_thread (in libpthread-?.?.so)
+   by 0x........: clone (in /...libc...)
+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)
+
+Conflicting store by thread 2 at 0x........ size 4
+   at 0x........: thread (rwlock_race.c:?)
+   by 0x........: vg_thread_wrapper (drd_intercepts.c:?)
+   by 0x........: start_thread (in libpthread-?.?.so)
+   by 0x........: clone (in /...libc...)
+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)
+Result: 2
+
+ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Added: trunk/exp-drd/tests/rwlock_race.vgtest
===================================================================
--- trunk/exp-drd/tests/rwlock_race.vgtest                              (rev 0)
+++ trunk/exp-drd/tests/rwlock_race.vgtest      2008-03-03 20:31:58 UTC (rev 
7549)
@@ -0,0 +1 @@
+prog: rwlock_race

Modified: trunk/exp-drd/tests/tc06_two_races.stderr.exp
===================================================================
--- trunk/exp-drd/tests/tc06_two_races.stderr.exp       2008-03-03 17:40:31 UTC 
(rev 7548)
+++ trunk/exp-drd/tests/tc06_two_races.stderr.exp       2008-03-03 20:31:58 UTC 
(rev 7549)
@@ -1 +1 @@
-ERROR SUMMARY: 2 errors from 2 contexts
+ERROR SUMMARY: 4 errors from 4 contexts

Modified: trunk/exp-drd/tests/tc21_pthonce.stderr.exp
===================================================================
--- trunk/exp-drd/tests/tc21_pthonce.stderr.exp 2008-03-03 17:40:31 UTC (rev 
7548)
+++ trunk/exp-drd/tests/tc21_pthonce.stderr.exp 2008-03-03 20:31:58 UTC (rev 
7549)
@@ -1,3 +1,45 @@
 
+Thread 2:
+Conflicting load by thread 2 at 0x........ size 4
+   at 0x........: vfprintf (in /...libc...)
+   by 0x........: printf (in /...libc...)
+   by 0x........: child (tc21_pthonce.c:73)
+   by 0x........: vg_thread_wrapper (drd_intercepts.c:?)
+   by 0x........: start_thread (in libpthread-?.?.so)
+   by 0x........: clone (in /...libc...)
+Allocation context: unknown
+Other segment start (thread 1)
+   at 0x........: clone (in /...libc...)
+   by 0x........: do_clone (in libpthread-?.?.so)
+   by 0x........: pthread_create@@GLIBC_2.2.5 (in libpthread-?.?.so)
+   by 0x........: pthread_create* (drd_intercepts.c:?)
+   by 0x........: main (tc21_pthonce.c:86)
+Other segment end (thread 1)
+   at 0x........: clone (in /...libc...)
+   by 0x........: do_clone (in libpthread-?.?.so)
+   by 0x........: pthread_create@@GLIBC_2.2.5 (in libpthread-?.?.so)
+   by 0x........: pthread_create* (drd_intercepts.c:?)
+   by 0x........: main (tc21_pthonce.c:86)
 
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+Conflicting load by thread 2 at 0x........ size 4
+   at 0x........: vfprintf (in /...libc...)
+   by 0x........: printf (in /...libc...)
+   by 0x........: child (tc21_pthonce.c:73)
+   by 0x........: vg_thread_wrapper (drd_intercepts.c:?)
+   by 0x........: start_thread (in libpthread-?.?.so)
+   by 0x........: clone (in /...libc...)
+Allocation context: unknown
+Other segment start (thread 1)
+   at 0x........: clone (in /...libc...)
+   by 0x........: do_clone (in libpthread-?.?.so)
+   by 0x........: pthread_create@@GLIBC_2.2.5 (in libpthread-?.?.so)
+   by 0x........: pthread_create* (drd_intercepts.c:?)
+   by 0x........: main (tc21_pthonce.c:86)
+Other segment end (thread 1)
+   at 0x........: clone (in /...libc...)
+   by 0x........: do_clone (in libpthread-?.?.so)
+   by 0x........: pthread_create@@GLIBC_2.2.5 (in libpthread-?.?.so)
+   by 0x........: pthread_create* (drd_intercepts.c:?)
+   by 0x........: main (tc21_pthonce.c:86)
+
+ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Modified: trunk/glibc-2.X-drd.supp
===================================================================
--- trunk/glibc-2.X-drd.supp    2008-03-03 17:40:31 UTC (rev 7548)
+++ trunk/glibc-2.X-drd.supp    2008-03-03 20:31:58 UTC (rev 7549)
@@ -113,6 +113,14 @@
    fun:pthread_create*
 }
 {
+   pthread
+   exp-drd:ConflictingAccess
+   fun:clone
+   fun:do_clone
+   fun:pthread_create@@GLIBC_*
+   fun:pthread_create*
+}
+{
    pthread-glibc2.7-pthread_create
    exp-drd:ConflictingAccess
    fun:memset
@@ -127,6 +135,13 @@
 {
    pthread
    exp-drd:ConflictingAccess
+   fun:__pthread_mutex_cond_lock
+   fun:pthread_cond_wait@@GLIBC_*
+   fun:pthread_cond_wait*
+}
+{
+   pthread
+   exp-drd:ConflictingAccess
    fun:clone
    fun:pthread_create@@GLIBC_*
    fun:pthread_create*


-------------------------------------------------------------------------
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