|
From: <sv...@va...> - 2016-09-19 14:16:44
|
Author: mjw
Date: Mon Sep 19 15:16:35 2016
New Revision: 15962
Log:
Workaround bar_bad testcase hanging with newer glibc in helgrind/drd tests.
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).
Added:
trunk/drd/tests/bar_bad.stderr.exp-nohang
- copied, changed from r15961, trunk/drd/tests/bar_bad.stderr.exp
trunk/drd/tests/bar_bad_xml.stderr.exp-nohang
- copied, changed from r15961, trunk/drd/tests/bar_bad_xml.stderr.exp
Modified:
trunk/drd/tests/Makefile.am
trunk/drd/tests/bar_bad.stderr.exp
trunk/drd/tests/bar_bad_xml.stderr.exp
trunk/helgrind/tests/Makefile.am
trunk/helgrind/tests/bar_bad.c
trunk/helgrind/tests/bar_bad.stderr.exp
Modified: trunk/drd/tests/Makefile.am
==============================================================================
--- trunk/drd/tests/Makefile.am (original)
+++ trunk/drd/tests/Makefile.am Mon Sep 19 15:16:35 2016
@@ -81,8 +81,10 @@
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 \
Modified: trunk/drd/tests/bar_bad.stderr.exp
==============================================================================
--- trunk/drd/tests/bar_bad.stderr.exp (original)
+++ trunk/drd/tests/bar_bad.stderr.exp Mon Sep 19 15:16:35 2016
@@ -34,16 +34,5 @@
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)
Copied: trunk/drd/tests/bar_bad.stderr.exp-nohang (from r15961, trunk/drd/tests/bar_bad.stderr.exp)
==============================================================================
--- trunk/drd/tests/bar_bad.stderr.exp (original)
+++ trunk/drd/tests/bar_bad.stderr.exp-nohang Mon Sep 19 15:16:35 2016
@@ -38,12 +38,5 @@
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)
Modified: trunk/drd/tests/bar_bad_xml.stderr.exp
==============================================================================
--- trunk/drd/tests/bar_bad_xml.stderr.exp (original)
+++ trunk/drd/tests/bar_bad_xml.stderr.exp Mon Sep 19 15:16:35 2016
@@ -204,78 +204,6 @@
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 @@
<count>...</count>
<unique>0x........</unique>
</pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
</errorcounts>
<suppcounts>...</suppcounts>
Copied: trunk/drd/tests/bar_bad_xml.stderr.exp-nohang (from r15961, trunk/drd/tests/bar_bad_xml.stderr.exp)
==============================================================================
--- trunk/drd/tests/bar_bad_xml.stderr.exp (original)
+++ trunk/drd/tests/bar_bad_xml.stderr.exp-nohang Mon Sep 19 15:16:35 2016
@@ -229,53 +229,6 @@
</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 @@
<count>...</count>
<unique>0x........</unique>
</pair>
- <pair>
- <count>...</count>
- <unique>0x........</unique>
- </pair>
</errorcounts>
<suppcounts>...</suppcounts>
Modified: trunk/helgrind/tests/Makefile.am
==============================================================================
--- trunk/helgrind/tests/Makefile.am (original)
+++ trunk/helgrind/tests/Makefile.am Mon Sep 19 15:16:35 2016
@@ -19,6 +19,7 @@
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 \
Modified: trunk/helgrind/tests/bar_bad.c
==============================================================================
--- trunk/helgrind/tests/bar_bad.c (original)
+++ trunk/helgrind/tests/bar_bad.c Mon Sep 19 15:16:35 2016
@@ -15,23 +15,27 @@
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 @@
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 @@
/* 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 @@
/* 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);
}
Modified: trunk/helgrind/tests/bar_bad.stderr.exp
==============================================================================
--- trunk/helgrind/tests/bar_bad.stderr.exp (original)
+++ trunk/helgrind/tests/bar_bad.stderr.exp Mon Sep 19 15:16:35 2016
@@ -8,14 +8,14 @@
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 @@
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 @@
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 @@
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 @@
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)
|