Author: sewardj
Date: 2007-10-30 19:08:01 +0000 (Tue, 30 Oct 2007)
New Revision: 7056

Log:
Add a test program for verifying that wrappers are really working.

Added:
   branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c
   branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
   branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stdout.exp
   branches/THRCHECK/thrcheck/tests/tc20_verifywrap.vgtest
Modified:
   branches/THRCHECK/thrcheck/tests/Makefile.am


Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am        2007-10-30 01:19:34 UTC 
(rev 7055)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am        2007-10-30 19:08:01 UTC 
(rev 7056)
@@ -67,7 +67,9 @@
                tc18_semabuse.stderr.exp-glibc25-x86 \
        tc19_shadowmem.vgtest tc19_shadowmem.stdout.exp \
                tc19_shadowmem.stderr.exp-glibc25-amd64 \
-               tc19_shadowmem.stderr.exp-glibc25-x86
+               tc19_shadowmem.stderr.exp-glibc25-x86 \
+       tc20_verifywrap.vgtest tc20_verifywrap.stdout.exp \
+               tc20_verifywrap.stderr.exp-glibc25-amd64
 
 
 check_PROGRAMS = \
@@ -95,7 +97,8 @@
        tc16_byterace \
        tc17_sembar \
        tc18_semabuse \
-       tc19_shadowmem
+       tc19_shadowmem \
+       tc20_verifywrap
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
                 -I$(top_srcdir)/coregrind -I$(top_builddir)/include \

Added: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c                          
(rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.c  2007-10-30 19:08:01 UTC 
(rev 7056)
@@ -0,0 +1,235 @@
+
+/* This program attempts to verify that all functions that are
+   supposed to be wrapped by tc_intercepts.c really are wrapped.  The
+   main way it does this is to cause failures in those functions, so
+   as to obtain various error messages which imply that the wrapper
+   really did engage.
+
+   Any regressions shown up by this program are potentially serious
+   and should be investigated carefully. */
+
+/* Needed for older glibcs (2.3 and older, at least) who don't
+   otherwise "know" about some more exotic pthread stuff, in this case
+   PTHREAD_MUTEX_ERRORCHECK. */
+#define _GNU_SOURCE 1
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+short unprotected = 0;
+
+void* lazy_child ( void* v ) {
+   assert(0); /* does not run */
+}
+
+void* racy_child ( void* v ) {
+   unprotected = 1234;
+   return NULL;
+}
+
+int main ( void )
+{
+   int r;
+   /* pthread_t thr; */
+   /* pthread_attr_t thra; */
+   pthread_mutexattr_t mxa, mxa2;
+   pthread_mutex_t mx, mx2, mx3, mx4;
+   pthread_cond_t cv;
+   struct timespec abstime;
+   pthread_rwlock_t rwl;
+   pthread_rwlock_t rwl2;
+   pthread_rwlock_t rwl3;
+   sem_t s1;
+
+   /* --------- pthread_create/join --------- */
+
+   fprintf(stderr,
+   "\n---------------- pthread_create/join ----------------\n\n");
+
+   /* make pthread_create fail */
+   /* It's amazingly difficult to make pthread_create fail
+      without first soaking up all the machine's resources.
+      Instead, in order to demonstrate that it's really wrapped,
+      create a child thread, generate a race error, and join with it
+      again. */
+   /* This just segfaults:
+      memset( &thra, 0xFF, sizeof(thra) );
+      r= pthread_create( &thr, NULL, lazy_child, NULL ); assert(r);
+   */
+   { pthread_t child;
+     r= pthread_create( &child, NULL, racy_child, NULL ); assert(!r);
+     sleep(1); /* just to ensure parent thread reports race, not child */
+     unprotected = 5678;
+     r= pthread_join( child, NULL ); assert(!r);
+   }
+
+   /* make pthread_join fail */
+   r= pthread_join( pthread_self(), NULL ); assert(r);
+
+   /* --------- pthread_mutex_lock et al --------- */
+
+   fprintf(stderr,
+   "\n---------------- pthread_mutex_lock et al ----------------\n\n");
+
+   /* make pthread_mutex_init fail */
+   memset( &mxa, 0xFF, sizeof(mxa) );
+   r= pthread_mutex_init( &mx, &mxa ); assert(r);
+
+   /* make pthread_mutex_destroy fail */
+   r= pthread_mutex_init( &mx2, NULL ); assert(!r);
+   r= pthread_mutex_lock( &mx2 ); assert(!r);
+   r= pthread_mutex_destroy( &mx2 ); assert(r);
+
+   /* make pthread_mutex_lock fail */
+   memset( &mx3, 0xFF, sizeof(mx3) );
+   r= pthread_mutex_lock( &mx3 ); assert(r);
+
+   /* make pthread_mutex_trylock fail */
+   memset( &mx3, 0xFF, sizeof(mx3) );
+   r= pthread_mutex_trylock( &mx3 ); assert(r);
+
+   /* make pthread_mutex_timedlock fail */
+   memset( &abstime, 0, sizeof(abstime) );
+   memset( &mx3, 0xFF, sizeof(mx3) );
+   r= pthread_mutex_timedlock( &mx3, &abstime ); assert(r);
+
+   /* make pthread_mutex_unlock fail */
+   memset( &mx3, 0xFF, sizeof(mx3) );
+   r= pthread_mutex_unlock( &mx3 ); assert(r);
+
+   /* --------- pthread_cond_wait et al --------- */
+
+   fprintf(stderr,
+   "\n---------------- pthread_cond_wait et al ----------------\n\n");
+
+   /* make pthread_cond_wait fail.  This is difficult.  Our cunning
+      plan (tm) is to show up at pthread_cond_wait bearing a
+      not-locked mutex of the ERRORCHECK flavour and hope (as is
+      indeed the case with glibc-2.5) that pthread_cond_wait notices
+      it is not locked, and bounces our request. */
+   r= pthread_mutexattr_init( &mxa2 ); assert(!r);
+   r= pthread_mutexattr_settype( &mxa2, PTHREAD_MUTEX_ERRORCHECK );
+      assert(!r);
+   r= pthread_mutex_init( &mx4, &mxa2 ); assert(!r);
+   r= pthread_cond_init( &cv, NULL ); assert(!r);
+   r= pthread_cond_wait( &cv, &mx4 ); assert(r);
+   r= pthread_mutexattr_destroy( &mxa2 ); assert(!r);
+
+   /* make pthread_cond_signal fail.  FIXME: can't figure out how
+      to */
+   r= pthread_cond_signal( &cv ); assert(!r);
+   fprintf(stderr, "\nFIXME: can't figure out how to "
+                   "verify wrap of pthread_cond_signal\n\n");
+
+   /* make pthread_cond_broadcast fail.  FIXME: can't figure out how
+      to */
+   r= pthread_cond_broadcast( &cv ); assert(!r);
+   fprintf(stderr, "\nFIXME: can't figure out how to "
+                   "verify wrap of pthread_broadcast_signal\n\n");
+
+   /* make pthread_cond_timedwait fail. */
+   memset( &abstime, 0, sizeof(abstime) );
+   abstime.tv_nsec = 1000000000 + 1;
+   r= pthread_cond_timedwait( &cv, &mx4, &abstime ); assert(r);
+
+   /* --------- pthread_rwlock_* --------- */
+
+   fprintf(stderr,
+   "\n---------------- pthread_rwlock_* ----------------\n\n");
+
+   /* pthread_rwlock_init, pthread_rwlock_unlock */
+   /* pthread_rwlock_init: can't make glibc's implementation fail.
+      However, can demonstrate interceptedness by initialising but not
+      locking a lock and then unlocking it.  Then the unlock call
+      should say "first seen at .. the init call."  So this tests
+      wrappedness of both calls. */
+   r= pthread_rwlock_init( &rwl, NULL ); assert(!r);
+   r= pthread_rwlock_unlock( &rwl ); 
+   /* assert(r); *//* glibc doesn't complain.  It really ought to. Oh well. */
+
+   /* We can infer the presence of wrapping for pthread_rwlock_rdlock,
+      pthread_rwlock_wrlock and pthread_rwlock_unlock by making
+      Thrcheck count the lockedness state, and warning when we unlock
+      a not-locked lock.  Thusly: */
+   r= pthread_rwlock_init( &rwl2, NULL ); assert(!r);
+
+   /* w-lock it */
+   fprintf(stderr, "(1) no error on next line\n");
+   r= pthread_rwlock_wrlock( &rwl2 ); assert(!r);
+   /* unlock it */
+   fprintf(stderr, "(2) no error on next line\n");
+   r= pthread_rwlock_unlock( &rwl2 ); assert(!r);
+   /* unlock it again, get an error */
+   fprintf(stderr, "(3)    ERROR on next line\n");
+   r= pthread_rwlock_unlock( &rwl2 ); assert(!r);
+
+   /* same game with r-locks */
+   r= pthread_rwlock_init( &rwl2, NULL ); assert(!r);
+   /* r-lock it twice */
+   fprintf(stderr, "(4) no error on next line\n");
+   r= pthread_rwlock_rdlock( &rwl2 ); assert(!r);
+   fprintf(stderr, "(5) no error on next line\n");
+   r= pthread_rwlock_rdlock( &rwl2 ); assert(!r);
+   /* unlock it twice */
+   fprintf(stderr, "(6) no error on next line\n");
+   r= pthread_rwlock_unlock( &rwl2 ); assert(!r);
+   fprintf(stderr, "(7) no error on next line\n");
+   r= pthread_rwlock_unlock( &rwl2 ); assert(!r);
+   /* unlock it again, get an error */
+   fprintf(stderr, "(8)    ERROR on next line\n");
+   r= pthread_rwlock_unlock( &rwl2 ); assert(!r);
+
+   /* Lock rwl3 so the locked-lock-at-dealloc check can complain about
+      it. */
+   r= pthread_rwlock_init( &rwl3, NULL ); assert(!r);
+   r= pthread_rwlock_rdlock( &rwl3 ); assert(!r);
+
+   /* ------------- sem_* ------------- */
+
+   /* This is pretty lame, and duplicates tc18_semabuse.c. */
+
+   fprintf(stderr,
+   "\n---------------- sem_* ----------------\n\n");
+
+   /* verifies wrap of sem_init */
+   /* Do sem_init with huge initial count - fails */
+   r= sem_init(&s1, 0, ~0); assert(r);
+
+   /* initialise properly */
+   r= sem_init(&s1, 0, 0);
+
+   /* in glibc, sem_destroy is a no-op; making it fail is
+      impossible. */
+   fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of "
+                   "sem_destroy\n\n");
+
+   /* verifies wrap of sem_wait */
+   /* Do 'wait' on a bogus semaphore.  This should fail, but on glibc
+      it succeeds. */
+   memset(&s1, 0x55, sizeof(s1));
+   r= sem_wait(&s1); /* assert(r != 0); */
+
+   /* this really ought to fail, but it doesn't. */
+   r= sem_post(&s1); assert(!r);
+   fprintf(stderr, "\nFIXME: can't figure out how to verify wrap of "
+                   "sem_post\n\n");
+
+   sem_destroy(&s1);
+
+   /* ------------- dealloc of mem holding locks ------------- */
+
+   fprintf(stderr,
+   "\n------------ dealloc of mem holding locks ------------\n\n");
+
+   /* At this point it should complain about deallocation
+      of memory containing locked locks:
+         mx4
+         rwl3
+   */
+
+   return 0;
+}

Added: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64   
                        (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stderr.exp-glibc25-amd64   
2007-10-30 19:08:01 UTC (rev 7056)
@@ -0,0 +1,158 @@
+
+
+---------------- pthread_create/join ----------------
+
+Thread #1 is the program's root thread
+
+Thread #2 was created
+   at 0x........: clone (in /...libc...)
+   by 0x........: ...
+   by 0x........: [EMAIL PROTECTED] (in /lib/libpthread...)
+   by 0x........: [EMAIL PROTECTED] (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:64)
+
+Possible data race during write of size 2 at 0x........
+   at 0x........: main (tc20_verifywrap.c:66)
+  Old state: owned exclusively by thread #2
+  New state: shared-modified by threads #1, #2
+  Reason:    this thread, #1, holds no locks at all
+
+Thread #1's call to pthread_join failed
+   with error code 35 (EDEADLK: Resource deadlock would occur)
+   at 0x........: pthread_join (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:71)
+
+---------------- pthread_mutex_lock et al ----------------
+
+
+Thread #1's call to pthread_mutex_init failed
+   with error code 95 (EOPNOTSUPP: Operation not supported on transport 
endpoint)
+   at 0x........: pthread_mutex_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:80)
+
+Thread #1: pthread_mutex_destroy of a locked mutex
+   at 0x........: pthread_mutex_destroy (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:85)
+
+Thread #1's call to pthread_mutex_destroy failed
+   with error code 16 (EBUSY: Device or resource busy)
+   at 0x........: pthread_mutex_destroy (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:85)
+
+Thread #1's call to pthread_mutex_lock failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: pthread_mutex_lock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:89)
+
+Thread #1's call to pthread_mutex_trylock failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: pthread_mutex_trylock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:93)
+
+Thread #1's call to pthread_mutex_timedlock failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: pthread_mutex_timedlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:98)
+
+Thread #1 unlocked an invalid lock at 0x........ 
+   at 0x........: pthread_mutex_unlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:102)
+
+Thread #1's call to pthread_mutex_unlock failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: pthread_mutex_unlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:102)
+
+---------------- pthread_cond_wait et al ----------------
+
+
+Thread #1 unlocked a not-locked lock at 0x........ 
+   at 0x........: [EMAIL PROTECTED] (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:119)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_mutex_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:117)
+
+Thread #1's call to pthread_cond_wait failed
+   with error code 1 (EPERM: Operation not permitted)
+   at 0x........: [EMAIL PROTECTED] (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:119)
+
+FIXME: can't figure out how to verify wrap of pthread_cond_signal
+
+
+FIXME: can't figure out how to verify wrap of pthread_broadcast_signal
+
+
+Thread #1's call to pthread_cond_timedwait failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: [EMAIL PROTECTED] (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:137)
+
+---------------- pthread_rwlock_* ----------------
+
+
+Thread #1 unlocked a not-locked lock at 0x........ 
+   at 0x........: pthread_rwlock_unlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:151)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:150)
+(1) no error on next line
+(2) no error on next line
+(3)    ERROR on next line
+
+Thread #1 unlocked a not-locked lock at 0x........ 
+   at 0x........: pthread_rwlock_unlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:168)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:158)
+(4) no error on next line
+(5) no error on next line
+(6) no error on next line
+(7) no error on next line
+(8)    ERROR on next line
+
+Thread #1 unlocked a not-locked lock at 0x........ 
+   at 0x........: pthread_rwlock_unlock (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:184)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:158)
+
+---------------- sem_* ----------------
+
+
+Thread #1's call to sem_init failed
+   with error code 22 (EINVAL: Invalid argument)
+   at 0x........: [EMAIL PROTECTED] (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:200)
+
+FIXME: can't figure out how to verify wrap of sem_destroy
+
+
+Thread #1: Bug in libpthread: sem_wait succeeded on semaphore without prior 
sem_post
+   at 0x........: sem_wait_WRK (tc_intercepts.c:...)
+   by 0x........: sem_wait (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:214)
+
+FIXME: can't figure out how to verify wrap of sem_post
+
+
+------------ dealloc of mem holding locks ------------
+
+
+Thread #1 deallocated location 0x........ containing a locked lock
+   at 0x........: main (tc20_verifywrap.c:235)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_rwlock_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:188)
+
+Thread #1 deallocated location 0x........ containing a locked lock
+   at 0x........: main (tc20_verifywrap.c:235)
+  Lock at 0x........ was first observed
+   at 0x........: pthread_mutex_init (tc_intercepts.c:...)
+   by 0x........: main (tc20_verifywrap.c:117)
+
+ERROR SUMMARY: 20 errors from 20 contexts (suppressed: 0 from 0)

Added: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.stdout.exp
===================================================================

Added: branches/THRCHECK/thrcheck/tests/tc20_verifywrap.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc20_verifywrap.vgtest                     
        (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc20_verifywrap.vgtest     2007-10-30 
19:08:01 UTC (rev 7056)
@@ -0,0 +1 @@
+prog: tc20_verifywrap


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to