Submitted By:            Douglas R. Reno
Date:                    2016-02-24
Initial Package Version: 3.11.0
Origin:                  http://pkgs.fedoraproject.org/cgit/rpms/valgrind.git/plain/valgrind-3.11.0-pthread_barrier.patch
Description:             This patch fixes a bug regarding the pthread_barrier function in Glibc 2.23 that causes at least one
                         test to fail.

diff --git a/drd/tests/bar_bad.stderr.exp b/drd/tests/bar_bad.stderr.exp
index 75f121f..3581b08 100644
--- a/drd/tests/bar_bad.stderr.exp
+++ b/drd/tests/bar_bad.stderr.exp
@@ -34,16 +34,5 @@ barrier 0x........ was first observed at:
 
 
 destroy a barrier that was never initialised
-Not a barrier
-   at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?)
-   by 0x........: main (bar_bad.c:?)
-
-Destruction of barrier that is being waited upon: barrier 0x........
-   at 0x........: free (vg_replace_malloc.c:...)
-   by 0x........: main (bar_bad.c:?)
-barrier 0x........ was first observed at:
-   at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
-   by 0x........: main (bar_bad.c:?)
-
 
-ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 0 from 0)
diff --git a/drd/tests/bar_bad.stderr.exp b/drd/tests/bar_bad.stderr.exp-nohang
similarity index 79%
copy from drd/tests/bar_bad.stderr.exp
copy to drd/tests/bar_bad.stderr.exp-nohang
index 75f121f..44f9651 100644
--- a/drd/tests/bar_bad.stderr.exp
+++ b/drd/tests/bar_bad.stderr.exp-nohang
@@ -38,12 +38,5 @@ Not a barrier
    at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?)
    by 0x........: main (bar_bad.c:?)
 
-Destruction of barrier that is being waited upon: barrier 0x........
-   at 0x........: free (vg_replace_malloc.c:...)
-   by 0x........: main (bar_bad.c:?)
-barrier 0x........ was first observed at:
-   at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
-   by 0x........: main (bar_bad.c:?)
-
 
-ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 0 from 0)
+ERROR SUMMARY: 6 errors from 5 contexts (suppressed: 0 from 0)
diff --git a/drd/tests/bar_bad_xml.stderr.exp b/drd/tests/bar_bad_xml.stderr.exp
index acb9656..8539f75 100644
--- a/drd/tests/bar_bad_xml.stderr.exp
+++ b/drd/tests/bar_bad_xml.stderr.exp
@@ -204,78 +204,6 @@ destroy a barrier that has waiting threads
 
 
 destroy a barrier that was never initialised
-<error>
-  <unique>0x........</unique>
-  <tid>...</tid>
-  <kind>GenericErr</kind>
-  <what>Not a barrier</what>
-  <stack>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>pthread_barrier_destroy</fn>
-      <dir>...</dir>
-      <file>drd_pthread_intercepts.c</file>
-      <line>...</line>
-    </frame>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>main</fn>
-      <dir>...</dir>
-      <file>bar_bad.c</file>
-      <line>...</line>
-    </frame>
-  </stack>
-</error>
-
-<error>
-  <unique>0x........</unique>
-  <tid>...</tid>
-  <kind>BarrierErr</kind>
-  <what>Destruction of barrier that is being waited upon: barrier 0x........</what>
-  <stack>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>free</fn>
-      <dir>...</dir>
-      <file>vg_replace_malloc.c</file>
-      <line>...</line>
-    </frame>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>main</fn>
-      <dir>...</dir>
-      <file>bar_bad.c</file>
-      <line>...</line>
-    </frame>
-  </stack>
-  <first_observed_at>
-    <what>barrier</what>
-    <address>0x........</address>
-  <stack>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>pthread_barrier_init</fn>
-      <dir>...</dir>
-      <file>drd_pthread_intercepts.c</file>
-      <line>...</line>
-    </frame>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>main</fn>
-      <dir>...</dir>
-      <file>bar_bad.c</file>
-      <line>...</line>
-    </frame>
-  </stack>
-  </first_observed_at>
-</error>
-
 
 <status>
   <state>FINISHED</state>
@@ -299,14 +227,6 @@ destroy a barrier that was never initialised
     <count>...</count>
     <unique>0x........</unique>
   </pair>
-  <pair>
-    <count>...</count>
-    <unique>0x........</unique>
-  </pair>
-  <pair>
-    <count>...</count>
-    <unique>0x........</unique>
-  </pair>
 </errorcounts>
 
 <suppcounts>...</suppcounts>
diff --git a/drd/tests/bar_bad_xml.stderr.exp b/drd/tests/bar_bad_xml.stderr.exp-nohang
similarity index 82%
copy from drd/tests/bar_bad_xml.stderr.exp
copy to drd/tests/bar_bad_xml.stderr.exp-nohang
index acb9656..a47cd60 100644
--- a/drd/tests/bar_bad_xml.stderr.exp
+++ b/drd/tests/bar_bad_xml.stderr.exp-nohang
@@ -229,53 +229,6 @@ destroy a barrier that was never initialised
   </stack>
 </error>
 
-<error>
-  <unique>0x........</unique>
-  <tid>...</tid>
-  <kind>BarrierErr</kind>
-  <what>Destruction of barrier that is being waited upon: barrier 0x........</what>
-  <stack>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>free</fn>
-      <dir>...</dir>
-      <file>vg_replace_malloc.c</file>
-      <line>...</line>
-    </frame>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>main</fn>
-      <dir>...</dir>
-      <file>bar_bad.c</file>
-      <line>...</line>
-    </frame>
-  </stack>
-  <first_observed_at>
-    <what>barrier</what>
-    <address>0x........</address>
-  <stack>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>pthread_barrier_init</fn>
-      <dir>...</dir>
-      <file>drd_pthread_intercepts.c</file>
-      <line>...</line>
-    </frame>
-    <frame>
-      <ip>0x........</ip>
-      <obj>...</obj>
-      <fn>main</fn>
-      <dir>...</dir>
-      <file>bar_bad.c</file>
-      <line>...</line>
-    </frame>
-  </stack>
-  </first_observed_at>
-</error>
-
 
 <status>
   <state>FINISHED</state>
@@ -303,10 +256,6 @@ destroy a barrier that was never initialised
     <count>...</count>
     <unique>0x........</unique>
   </pair>
-  <pair>
-    <count>...</count>
-    <unique>0x........</unique>
-  </pair>
 </errorcounts>
 
 <suppcounts>...</suppcounts>
diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am
index 8a0d6e6..df82169 100644
--- a/helgrind/tests/Makefile.am
+++ b/helgrind/tests/Makefile.am
@@ -19,6 +19,7 @@ EXTRA_DIST = \
 	cond_timedwait_test.vgtest cond_timedwait_test.stdout.exp \
 		cond_timedwait_test.stderr.exp \
 	bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \
+		bar_bad.stderr.exp-destroy-hang \
 	bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \
 	free_is_write.vgtest free_is_write.stdout.exp \
 		free_is_write.stderr.exp \
diff --git a/helgrind/tests/bar_bad.c b/helgrind/tests/bar_bad.c
index dd6079c..424ae2f 100644
--- a/helgrind/tests/bar_bad.c
+++ b/helgrind/tests/bar_bad.c
@@ -15,23 +15,27 @@ void* child1 ( void* arg )
    return NULL;
 }
 
+void *sleep1 ( void* arg )
+{
+   /* Long sleep, we hope to never trigger. */
+   sleep (6);
+   pthread_barrier_wait ( (pthread_barrier_t*)arg );
+   return NULL;
+}
+
+void *exit1 ( void* arg )
+{
+   /* Sleep a bit, then exit, we are done. */
+   sleep (1);
+   exit (0);
+   return NULL;
+}
+
 int main ( void )
 {
   pthread_barrier_t *bar1, *bar2, *bar3, *bar4, *bar5;
-  pthread_t thr1, thr2;
   int r;
-
-  /* possibly set up a watchdog timer thread here. */
-
-
-
-
-
-
-
-
-
-
+  pthread_t thr1, thr2, slp1, slp2, ext1;
 
   /* initialise a barrier with a zero count */
   fprintf(stderr, "\ninitialise a barrier with zero count\n");
@@ -49,6 +53,9 @@ int main ( void )
   fprintf(stderr, "\ninitialise a barrier which has threads waiting on it\n");
   bar3 = malloc(sizeof(pthread_barrier_t));
   pthread_barrier_init(bar3, NULL, 2);
+  /* create a thread, whose purpose is to "unblock" the barrier after
+     some sleeping in case it keeps being blocked.  */
+  pthread_create(&slp1, NULL, sleep1, (void*)bar3);
   /* create a thread, whose only purpose is to block on the barrier */
   pthread_create(&thr1, NULL, child1, (void*)bar3);
   /* guarantee that it gets there first */
@@ -61,6 +68,12 @@ int main ( void )
   /* once again, create a thread, whose only purpose is to block. */
   bar4 = malloc(sizeof(pthread_barrier_t));
   pthread_barrier_init(bar4, NULL, 2);
+  /* create a thread, whose purpose is to "unblock" the barrier after
+     some sleeping in case it keeps being blocked. We hope it isn't
+     needed, but if it is, because pthread_barier_destroy hangs
+     and we will get an extra warning about the barrier being already
+     destroyed. */
+  pthread_create(&slp2, NULL, sleep1, (void*)bar4);
   /* create a thread, whose only purpose is to block on the barrier */
   pthread_create(&thr2, NULL, child1, (void*)bar4);
   /* guarantee that it gets there first */
@@ -70,13 +83,16 @@ int main ( void )
 
   /* destroy a barrier that was never initialised.  This is a bit
      tricky, in that we have to fill the barrier with bytes which
-     ensure that the pthread_barrier_destroy call doesn't hang for
-     some reason.  Zero-fill seems to work ok on amd64-linux (glibc
+     ensure that the pthread_barrier_destroy call doesn't crash for
+     some reason.  One-fill seems to work ok on amd64-linux (glibc
      2.8). */
   fprintf(stderr, "\ndestroy a barrier that was never initialised\n");
+  /* Create a thread that just exits the process after some sleep.
+     We are really done at this point, even if we hang. */
+  pthread_create(&ext1, NULL, exit1, NULL);
   bar5 = malloc(sizeof(pthread_barrier_t));
   assert(bar5);
-  memset(bar5, 0, sizeof(*bar5));
+  memset(bar5, 1, sizeof(*bar5));
   pthread_barrier_destroy(bar5);
 
   /* now we need to clean up the mess .. */
@@ -85,5 +101,6 @@ int main ( void )
 
   free(bar1); free(bar2); free(bar3); free(bar4); free(bar5);
 
-  return 0;
+  /* Use exit, we want to kill any "sleeper threads". */
+  exit (0);
 }
diff --git a/helgrind/tests/bar_bad.stderr.exp b/helgrind/tests/bar_bad.stderr.exp
index 74af4fa..d0901b2 100644
--- a/helgrind/tests/bar_bad.stderr.exp
+++ b/helgrind/tests/bar_bad.stderr.exp
@@ -8,14 +8,14 @@ Thread #x is the program's root thread
 
 Thread #x: pthread_barrier_init: 'count' argument is zero
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:39)
+   by 0x........: main (bar_bad.c:43)
 
 ----------------------------------------------------------------
 
 Thread #x's call to pthread_barrier_init failed
    with error code 22 (EINVAL: Invalid argument)
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:39)
+   by 0x........: main (bar_bad.c:43)
 
 
 initialise a barrier twice
@@ -23,7 +23,7 @@ initialise a barrier twice
 
 Thread #x: pthread_barrier_init: barrier is already initialised
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:45)
+   by 0x........: main (bar_bad.c:49)
 
 
 initialise a barrier which has threads waiting on it
@@ -31,13 +31,13 @@ initialise a barrier which has threads waiting on it
 
 Thread #x: pthread_barrier_init: barrier is already initialised
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:57)
+   by 0x........: main (bar_bad.c:64)
 
 ----------------------------------------------------------------
 
 Thread #x: pthread_barrier_init: threads are waiting at barrier
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:57)
+   by 0x........: main (bar_bad.c:64)
 
 
 destroy a barrier that has waiting threads
@@ -45,14 +45,14 @@ destroy a barrier that has waiting threads
 
 Thread #x: pthread_barrier_destroy: threads are waiting at barrier
    at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:69)
+   by 0x........: main (bar_bad.c:82)
 
 ----------------------------------------------------------------
 
 Thread #x's call to pthread_barrier_destroy failed
    with error code 16 (EBUSY: Device or resource busy)
    at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:69)
+   by 0x........: main (bar_bad.c:82)
 
 
 destroy a barrier that was never initialised
@@ -60,5 +60,5 @@ destroy a barrier that was never initialised
 
 Thread #x: pthread_barrier_destroy: barrier was never initialised
    at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:80)
+   by 0x........: main (bar_bad.c:96)
 
diff --git a/helgrind/tests/bar_bad.stderr.exp b/helgrind/tests/bar_bad.stderr.exp-destroy-hang
similarity index 72%
copy from helgrind/tests/bar_bad.stderr.exp
copy to helgrind/tests/bar_bad.stderr.exp-destroy-hang
index 74af4fa..ddf5624 100644
--- a/helgrind/tests/bar_bad.stderr.exp
+++ b/helgrind/tests/bar_bad.stderr.exp-destroy-hang
@@ -8,14 +8,14 @@ Thread #x is the program's root thread
 
 Thread #x: pthread_barrier_init: 'count' argument is zero
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:39)
+   by 0x........: main (bar_bad.c:43)
 
 ----------------------------------------------------------------
 
 Thread #x's call to pthread_barrier_init failed
    with error code 22 (EINVAL: Invalid argument)
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:39)
+   by 0x........: main (bar_bad.c:43)
 
 
 initialise a barrier twice
@@ -23,7 +23,7 @@ initialise a barrier twice
 
 Thread #x: pthread_barrier_init: barrier is already initialised
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:45)
+   by 0x........: main (bar_bad.c:49)
 
 
 initialise a barrier which has threads waiting on it
@@ -31,13 +31,13 @@ initialise a barrier which has threads waiting on it
 
 Thread #x: pthread_barrier_init: barrier is already initialised
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:57)
+   by 0x........: main (bar_bad.c:64)
 
 ----------------------------------------------------------------
 
 Thread #x: pthread_barrier_init: threads are waiting at barrier
    at 0x........: pthread_barrier_init (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:57)
+   by 0x........: main (bar_bad.c:64)
 
 
 destroy a barrier that has waiting threads
@@ -45,14 +45,22 @@ destroy a barrier that has waiting threads
 
 Thread #x: pthread_barrier_destroy: threads are waiting at barrier
    at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:69)
+   by 0x........: main (bar_bad.c:82)
+
+---Thread-Announcement------------------------------------------
+
+Thread #x was created
+   ...
+   by 0x........: pthread_create@* (hg_intercepts.c:...)
+   by 0x........: main (bar_bad.c:76)
 
 ----------------------------------------------------------------
 
-Thread #x's call to pthread_barrier_destroy failed
-   with error code 16 (EBUSY: Device or resource busy)
-   at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:69)
+Thread #x: pthread_barrier_wait: barrier is uninitialised
+   at 0x........: pthread_barrier_wait (hg_intercepts.c:...)
+   by 0x........: sleep1 (bar_bad.c:22)
+   by 0x........: mythread_wrapper (hg_intercepts.c:...)
+   ...
 
 
 destroy a barrier that was never initialised
@@ -60,5 +68,5 @@ destroy a barrier that was never initialised
 
 Thread #x: pthread_barrier_destroy: barrier was never initialised
    at 0x........: pthread_barrier_destroy (hg_intercepts.c:...)
-   by 0x........: main (bar_bad.c:80)
+   by 0x........: main (bar_bad.c:96)
 
-- 
1.8.3.1

