]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix false positive following pthread_cond_timedwait failure.
authorJulian Seward <jseward@acm.org>
Wed, 19 Oct 2011 05:41:34 +0000 (05:41 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 19 Oct 2011 05:41:34 +0000 (05:41 +0000)
Fixes #271917.  (Philippe Waroquiers, philippe.waroquiers@skynet.be)

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

helgrind/hg_intercepts.c
helgrind/tests/Makefile.am
helgrind/tests/cond_timedwait_invalid.c [new file with mode: 0644]
helgrind/tests/cond_timedwait_invalid.stderr.exp [new file with mode: 0644]
helgrind/tests/cond_timedwait_invalid.stdout.exp [new file with mode: 0644]
helgrind/tests/cond_timedwait_invalid.vgtest [new file with mode: 0644]

index aca790f8d810b92559cba2251fea840e0b1e3bb3..47b06450dcfb49290ddf9bdf11fa34373cbe2e68 100644 (file)
@@ -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,
index 254ab51951ea0c4132556e75fc06a3b4c7b0dbd1..b5178158e6e0df84c0e7e08f59fd41f4643c6b14 100644 (file)
@@ -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 (file)
index 0000000..c69ad22
--- /dev/null
@@ -0,0 +1,20 @@
+#include <time.h>
+#include <pthread.h>
+#include <assert.h>
+#include <errno.h>
+
+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 (file)
index 0000000..83401df
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/helgrind/tests/cond_timedwait_invalid.vgtest b/helgrind/tests/cond_timedwait_invalid.vgtest
new file mode 100644 (file)
index 0000000..58745cd
--- /dev/null
@@ -0,0 +1,2 @@
+prog: cond_timedwait_invalid
+