From ebed60be0bf3fb8a937801785a38f08c65169d76 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Jan 19 2016 17:45:44 +0000 Subject: 3.11.0-7 - Add valgrind-3.11.0-pthread_barrier.patch --- diff --git a/valgrind-3.11.0-pthread_barrier.patch b/valgrind-3.11.0-pthread_barrier.patch new file mode 100644 index 0000000..d06e2db --- /dev/null +++ b/valgrind-3.11.0-pthread_barrier.patch @@ -0,0 +1,294 @@ +From 3a30870111f1ce95d5715e66387d60548927c703 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Tue, 19 Jan 2016 15:13:47 +0100 +Subject: [PATCH] pthread_barrier vs newer glibc implementation + +glibc 2.23 will have a new pthread_barrier implementation. +This implementation reacts differently on bad usage of barriers. +Because of this the bar_bad testcase will hang indefinitely. +In particular pthread_barrier_destroy will hang when there are +still other threads waiting on a barrier. To solve this we add +extra threads to will "unblock" the hanging destroy by sleeping +for a while and then also waiting on the barrier, which will unblock +the destroy operation. Or if this is the last test, just exit +the whole program since we are done anyway. Also newer glibc is +more picky about destroying uninitialized barriers, we would crash +when zero filling, so we now one fill. Which doesn't crash, but +depending on glibc version might return an error or hang. Since +depending on version we now get slightly different error reports +there are now alternative exp files. + +Tested against glibc 2.17, glibc 2.22 and glibc 2.23-prerelease. +--- + helgrind/tests/Makefile.am | 1 + + helgrind/tests/bar_bad.c | 51 ++++++++++++++-------- + helgrind/tests/bar_bad.stderr.exp | 16 +++---- + ....stderr.exp => bar_bad.stderr.exp-destroy-hang} | 30 ++++++++----- + 4 files changed, 62 insertions(+), 36 deletions(-) + copy helgrind/tests/{bar_bad.stderr.exp => bar_bad.stderr.exp-destroy-hang} (72%) + +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 + diff --git a/valgrind.spec b/valgrind.spec index 0c17dbc..8f057cb 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -3,7 +3,7 @@ Summary: Tool for finding memory management bugs in programs Name: %{?scl_prefix}valgrind Version: 3.11.0 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 1 License: GPLv2+ URL: http://www.valgrind.org/ @@ -76,6 +76,9 @@ Patch9: valgrind-3.11.0-wrapmalloc.patch # RHBZ#1283774 - Valgrind: FATAL: aspacem assertion failed Patch10: valgrind-3.11.0-aspacemgr.patch +# KDE#358213 - helgrind bar_bad testcase hangs with new glibc pthread barrier +Patch11: valgrind-3.11.0-pthread_barrier.patch + %if %{build_multilib} # Ensure glibc{,-devel} is installed for both multilib arches BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so @@ -190,6 +193,7 @@ Valgrind User Manual for details. %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 %build # We need to use the software collection compiler and binutils if available. @@ -365,6 +369,9 @@ echo ===============END TESTING=============== %endif %changelog +* Tue Jan 19 2016 Mark Wielaard - 3.11.0-7 +- Add valgrind-3.11.0-pthread_barrier.patch + * Sat Jan 16 2016 Mark Wielaard - 3.11.0-6 - Add valgrind-3.11.0-aspacemgr.patch (#1283774)