]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Workaround bar_bad testcase hanging with newer glibc in helgrind/drd tests.
authorMark Wielaard <mark@klomp.org>
Mon, 19 Sep 2016 14:16:35 +0000 (14:16 +0000)
committerMark Wielaard <mark@klomp.org>
Mon, 19 Sep 2016 14:16:35 +0000 (14:16 +0000)
This is a workaround for bug #358213 helgrind/drd pthread_barrier tests
hangs with new glibc pthread barrier implementation. This makes sure that
the tests don't hang anymore. It does this by creating new threads that
sleep and kill the other threads after some time. But this introduces
some non-determinism that might cause the tests to occassionally fail
(both against old and new glibc implementations).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15962

drd/tests/Makefile.am
drd/tests/bar_bad.stderr.exp
drd/tests/bar_bad.stderr.exp-nohang [new file with mode: 0644]
drd/tests/bar_bad_xml.stderr.exp
drd/tests/bar_bad_xml.stderr.exp-nohang [new file with mode: 0644]
helgrind/tests/Makefile.am
helgrind/tests/bar_bad.c
helgrind/tests/bar_bad.stderr.exp

index 2885391638ee06148bf291a601f9a2dd54eed25a..cfd74d04c894528a65a438964ae5ffa874632366 100644 (file)
@@ -81,8 +81,10 @@ EXTRA_DIST =                                        \
        atomic_var.stderr.exp                       \
        atomic_var.vgtest                           \
        bar_bad.stderr.exp                          \
+       bar_bad.stderr.exp-nohang                   \
        bar_bad.vgtest                              \
        bar_bad_xml.stderr.exp                      \
+       bar_bad_xml.stderr.exp-nohang               \
        bar_bad_xml.vgtest                          \
        bar_trivial.stderr.exp                      \
        bar_trivial.stdout.exp                      \
index 75f121f146bfd5fac4d525b09f76bc078910b50e..3581b085dd03ec94d2a3a26a723561969c6d0179 100644 (file)
@@ -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-nohang b/drd/tests/bar_bad.stderr.exp-nohang
new file mode 100644 (file)
index 0000000..44f9651
--- /dev/null
@@ -0,0 +1,42 @@
+
+
+initialise a barrier with zero count
+pthread_barrier_init: 'count' argument is zero: barrier 0x........
+   at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
+   by 0x........: main (bar_bad.c:?)
+
+
+initialise a barrier twice
+Barrier reinitialization: barrier 0x........
+   at 0x........: pthread_barrier_init (drd_pthread_intercepts.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:?)
+
+
+initialise a barrier which has threads waiting on it
+Barrier reinitialization: barrier 0x........
+   at 0x........: pthread_barrier_init (drd_pthread_intercepts.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:?)
+
+
+destroy a barrier that has waiting threads
+Destruction of a barrier with active waiters: barrier 0x........
+   at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.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:?)
+
+
+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:?)
+
+
+ERROR SUMMARY: 6 errors from 5 contexts (suppressed: 0 from 0)
index acb965656e9a6299f2b5d8a2ee4e3d5e20ac9e37..8539f75c77a0e22774df35c0f6108ff0c26ec971 100644 (file)
@@ -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-nohang b/drd/tests/bar_bad_xml.stderr.exp-nohang
new file mode 100644 (file)
index 0000000..a47cd60
--- /dev/null
@@ -0,0 +1,264 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./../../helgrind/tests/bar_bad</exe>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+
+initialise a barrier with zero count
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>pthread_barrier_init: 'count' argument is zero: barrier 0x........</what>
+  <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>
+</error>
+
+
+initialise a barrier twice
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Barrier reinitialization: barrier 0x........</what>
+  <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>
+    <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>
+
+
+initialise a barrier which has threads waiting on it
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Barrier reinitialization: barrier 0x........</what>
+  <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>
+    <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>
+
+
+destroy a barrier that has waiting threads
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>BarrierErr</kind>
+  <what>Destruction of a barrier with active waiters: barrier 0x........</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>
+  <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>
+
+
+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>
+
+
+<status>
+  <state>FINISHED</state>
+  <time>...</time>
+</status>
+
+<errorcounts>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+  <pair>
+    <count>...</count>
+    <unique>0x........</unique>
+  </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
index 8a0d6e650db768f115050d89d3b7196e56e065bd..df82169fb37994b5f7307514c091e928fb3adb3e 100644 (file)
@@ -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 \
index dd6079c90478f9c47ef98583ed6bd8090c775d1d..8ead816e173b07bebc8964fa1d6075220d47ea5f 100644 (file)
@@ -15,23 +15,27 @@ void* child1 ( void* arg )
    return NULL;
 }
 
+void *sleep1 ( void* arg )
+{
+   /* Long sleep, we hope to never trigger. */
+   sleep (10);
+   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,20 +83,24 @@ 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 .. */
-  r= pthread_cancel(thr1); assert(!r);
-  r= pthread_cancel(thr2); assert(!r);
+  /* now we need to clean up the mess .. But skip canceling threads.  */
+  /* r= pthread_cancel(thr1); assert(!r); // drd doesn't like it. Just exit.
+  r= pthread_cancel(thr2); assert(!r); */
 
   free(bar1); free(bar2); free(bar3); free(bar4); free(bar5);
 
-  return 0;
+  /* Use exit, we want to kill any "sleeper threads". */
+  exit (0);
 }
index 74af4fa562a328a35600bac03421927294de7849..d0901b23318613ddff5cfe2114f0ade7d72c020f 100644 (file)
@@ -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)