From: Bart Van Assche Date: Sun, 22 Feb 2009 09:26:22 +0000 (+0000) Subject: Added regression test for detection of unsynchronized pthread_barrier_wait() and... X-Git-Tag: svn/VALGRIND_3_5_0~950 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9078874b5c5203a68111ed02ef717969b9e90def;p=thirdparty%2Fvalgrind.git Added regression test for detection of unsynchronized pthread_barrier_wait() and pthread_barrier_delete() calls. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9215 --- diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index e397327536..ae1d769bb3 100644 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -81,6 +81,8 @@ EXTRA_DIST = \ pth_barrier2.vgtest \ pth_barrier3.stderr.exp \ pth_barrier3.vgtest \ + pth_barrier_race.stderr.exp \ + pth_barrier_race.vgtest \ pth_barrier_reinit.stderr.exp \ pth_barrier_reinit.vgtest \ pth_broadcast.stderr.exp \ @@ -226,7 +228,7 @@ check_PROGRAMS += omp_matinv omp_prime omp_printf endif if HAVE_PTHREAD_BARRIER -check_PROGRAMS += matinv pth_barrier pth_barrier_reinit +check_PROGRAMS += matinv pth_barrier pth_barrier_race pth_barrier_reinit endif if HAVE_PTHREAD_SPINLOCK diff --git a/drd/tests/pth_barrier_race.c b/drd/tests/pth_barrier_race.c new file mode 100644 index 0000000000..0c09a7bb75 --- /dev/null +++ b/drd/tests/pth_barrier_race.c @@ -0,0 +1,46 @@ +/* + * Test program that triggers a race between pthread_barrier_wait() and + * pthread_barrier_destroy(): proper synchronization is missing between + * the pthread_barrier_wait() and the pthread_barrier_destroy() calls. This + * test program is based on the example that was posted on February 5, 2009 by + * Christoph Bartoschek on the valgrind-users mailing list. Redistribution of + * the source code below is permitted under the GPLv2 license. + * + * See also http://article.gmane.org/gmane.comp.debugging.valgrind/8945/match=pthread_barrier_wait + */ + + +#include +#include + + +static pthread_barrier_t* barrier; + + +static void* thread(void* arg) +{ + pthread_barrier_wait(barrier); + return NULL; +} + +int main() +{ + pthread_t tid; + + barrier = (pthread_barrier_t *) malloc(sizeof(*barrier)); + pthread_barrier_init(barrier, NULL, 2); + + pthread_create(&tid, NULL, thread, NULL); + + pthread_barrier_wait(barrier); + /* + * The sleep() call below ensures that the pthread_barrier_destroy() call + * happens after the created thread has returned from pthread_barrier_wait(). + */ + sleep(1); + pthread_barrier_destroy(barrier); + free(barrier); + + pthread_join(tid, NULL); + return 0; +} diff --git a/drd/tests/pth_barrier_race.stderr.exp b/drd/tests/pth_barrier_race.stderr.exp new file mode 100644 index 0000000000..41cac74e1e --- /dev/null +++ b/drd/tests/pth_barrier_race.stderr.exp @@ -0,0 +1,15 @@ + +Destruction of barrier not synchronized with barrier wait call: barrier 0x........ + at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?) + by 0x........: main (pth_barrier_race.c:?) +Conflicting wait call by thread 0/2: + at 0x........: pthread_barrier_wait (drd_pthread_intercepts.c:?) + by 0x........: thread (pth_barrier_race.c:?) + by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?) + by 0x........: (within libpthread-?.?.so) + by 0x........: clone (in /...libc...) +barrier 0x........ was first observed at: + at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?) + by 0x........: main (pth_barrier_race.c:?) + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/drd/tests/pth_barrier_race.vgtest b/drd/tests/pth_barrier_race.vgtest new file mode 100644 index 0000000000..1f0e7ee84b --- /dev/null +++ b/drd/tests/pth_barrier_race.vgtest @@ -0,0 +1,2 @@ +prereq: test -e pth_barrier_race && ./supported_libpthread +prog: pth_barrier_race