From: Julian Seward Date: Wed, 19 Oct 2011 05:41:34 +0000 (+0000) Subject: Fix false positive following pthread_cond_timedwait failure. X-Git-Tag: svn/VALGRIND_3_7_0~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60c4f86e74a3c8fe0bd8d76a5543bc70b5177123;p=thirdparty%2Fvalgrind.git Fix false positive following pthread_cond_timedwait failure. Fixes #271917. (Philippe Waroquiers, philippe.waroquiers@skynet.be) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12164 --- diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index aca790f8d8..47b06450dc 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -733,6 +733,7 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond, int ret; OrigFn fn; unsigned long mutex_is_valid; + Bool abstime_is_valid; VALGRIND_GET_ORIG_FN(fn); if (TRACE_PTH_FNS) { @@ -749,17 +750,25 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond, pthread_cond_t*,cond, pthread_mutex_t*,mutex); assert(mutex_is_valid == 1 || mutex_is_valid == 0); + abstime_is_valid = abstime->tv_nsec >= 0 && abstime->tv_nsec < 1000000000; + /* Tell the tool we're about to drop the mutex. This reflects the fact that in a cond_wait, we show up holding the mutex, and the call atomically drops the mutex and waits for the cv to be signalled. */ - if (mutex_is_valid) { + if (mutex_is_valid && abstime_is_valid) { DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE, pthread_mutex_t*,mutex); } CALL_FN_W_WWW(ret, fn, cond,mutex,abstime); + if (!abstime_is_valid && ret != EINVAL) { + DO_PthAPIerror("Bug in libpthread: pthread_cond_timedwait " + "invalid abstime did not cause" + " EINVAL", ret); + } + if ((ret == 0 || ret == ETIMEDOUT) && mutex_is_valid) { /* and now we have the mutex again */ DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST, diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am index 254ab51951..b5178158e6 100644 --- a/helgrind/tests/Makefile.am +++ b/helgrind/tests/Makefile.am @@ -10,6 +10,8 @@ EXTRA_DIST = \ annotate_rwlock.stderr.exp \ annotate_smart_pointer.vgtest annotate_smart_pointer.stdout.exp \ annotate_smart_pointer.stderr.exp \ + cond_timedwait_invalid.vgtest cond_timedwait_invalid.stdout.exp \ + cond_timedwait_invalid.stderr.exp bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \ bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \ free_is_write.vgtest free_is_write.stdout.exp \ @@ -90,6 +92,7 @@ EXTRA_DIST = \ # should be conditionally compiled like tc20_verifywrap is. check_PROGRAMS = \ annotate_hbefore \ + cond_timedwait_invalid \ free_is_write \ hg01_all_ok \ hg02_deadlock \ @@ -179,4 +182,7 @@ else annotate_hbefore_CFLAGS = $(AM_CFLAGS) endif +if VGCONF_OS_IS_LINUX +cond_timedwait_invalid_LDADD = -lrt +endif diff --git a/helgrind/tests/cond_timedwait_invalid.c b/helgrind/tests/cond_timedwait_invalid.c new file mode 100644 index 0000000000..c69ad2220e --- /dev/null +++ b/helgrind/tests/cond_timedwait_invalid.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +int main() +{ + struct timespec abstime; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + + assert(clock_gettime(CLOCK_REALTIME, &abstime)==0); + abstime.tv_nsec += 1000000000; + + assert(pthread_mutex_lock(&mutex)==0); + assert(pthread_cond_timedwait(&cond, &mutex, &abstime)==EINVAL); + assert(pthread_mutex_unlock(&mutex)==0); + + return 0; +} diff --git a/helgrind/tests/cond_timedwait_invalid.stderr.exp b/helgrind/tests/cond_timedwait_invalid.stderr.exp new file mode 100644 index 0000000000..83401dff7a --- /dev/null +++ b/helgrind/tests/cond_timedwait_invalid.stderr.exp @@ -0,0 +1,15 @@ + +---Thread-Announcement------------------------------------------ + +Thread #x is the program's root thread + +---------------------------------------------------------------- + +Thread #x's call to pthread_cond_timedwait failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) + by 0x........: main (cond_timedwait_invalid.c:16) + + +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/helgrind/tests/cond_timedwait_invalid.stdout.exp b/helgrind/tests/cond_timedwait_invalid.stdout.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helgrind/tests/cond_timedwait_invalid.vgtest b/helgrind/tests/cond_timedwait_invalid.vgtest new file mode 100644 index 0000000000..58745cde3b --- /dev/null +++ b/helgrind/tests/cond_timedwait_invalid.vgtest @@ -0,0 +1,2 @@ +prog: cond_timedwait_invalid +