From: Tom Hughes Date: Tue, 18 Aug 2015 10:29:20 +0000 (+0000) Subject: Attempt to work around issues with xend being executed unconditionally X-Git-Tag: svn/VALGRIND_3_11_0~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b22d60778f38d333d18213dd69b034de475fc63d;p=thirdparty%2Fvalgrind.git Attempt to work around issues with xend being executed unconditionally when a pthread_rwlock is used in an invalid way. Recent glibcs use transactional memory instructions to do lock ellision but will sometimes, when locks are used in an invalid way, may calls to xend on systems which don't support it, on the grounds that the program is invalid anyway. So we try and catch and ignore the resulting SIGILL in our tests that deliberately work with invalid locks. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15565 --- diff --git a/drd/tests/tc12_rwl_trivial.stderr.exp b/drd/tests/tc12_rwl_trivial.stderr.exp index 554515d10e..1a67b3d603 100644 --- a/drd/tests/tc12_rwl_trivial.stderr.exp +++ b/drd/tests/tc12_rwl_trivial.stderr.exp @@ -1,6 +1,7 @@ Reader-writer lock not locked by calling thread: rwlock 0x......... at 0x........: pthread_rwlock_unlock (drd_pthread_intercepts.c:?) + by 0x........: safe_pthread_rwlock_unlock (safe-pthread.h:43) by 0x........: main (tc12_rwl_trivial.c:29) rwlock 0x........ was first observed at: at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?) diff --git a/drd/tests/tc12_rwl_trivial.vgtest b/drd/tests/tc12_rwl_trivial.vgtest index 0cb3825cbf..21e698113c 100644 --- a/drd/tests/tc12_rwl_trivial.vgtest +++ b/drd/tests/tc12_rwl_trivial.vgtest @@ -1,2 +1,3 @@ prereq: ./supported_libpthread +vgopts: --sigill-diagnostics=no prog: ../../helgrind/tests/tc12_rwl_trivial diff --git a/helgrind/tests/safe-pthread.h b/helgrind/tests/safe-pthread.h new file mode 100644 index 0000000000..1210f3a851 --- /dev/null +++ b/helgrind/tests/safe-pthread.h @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +static jmp_buf env; + +/* + * Starting with glibc 2.20 some pthread calls may execute + * an xend instruction unconditionally when a lock is used in + * a way that is invalid so defined a sigill handler that can + * convert these invalid instructions to a normal error. + */ +static void sigill_handler( int signum, siginfo_t *siginfo, void *sigcontext ) { + unsigned char *pc = siginfo->si_addr; + assert( pc[0] == 0x0f && pc[1] == 0x01 && pc[2] == 0xd5 ); + longjmp( env, EPERM ); +} + +/* + * Wrapper for pthread_rwlock_unlock which may execute xend + * unconditionally when used on a lock that is not locked. + * + * Note that we return 0 instead of EPERM because that is what + * glibc normally does - error reporting is optional. + */ +static int safe_pthread_rwlock_unlock( pthread_rwlock_t *rwlock ) { +#if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) ) + struct sigaction sa; + struct sigaction oldsa; + int r; + + sa.sa_handler = NULL; + sa.sa_sigaction = sigill_handler; + sigemptyset( &sa.sa_mask ); + sa.sa_flags = SA_SIGINFO; + sa.sa_restorer = NULL; + + sigaction( SIGILL, &sa, &oldsa ); + + if ( ( r = setjmp( env ) ) == 0 ) { + r = pthread_rwlock_unlock( rwlock ); + } else { + r = 0; + } + + sigaction( SIGILL, &oldsa, NULL ); + + return r; +#else + return pthread_rwlock_unlock( rwlock ); +#endif +} + +#define pthread_rwlock_unlock safe_pthread_rwlock_unlock diff --git a/helgrind/tests/tc12_rwl_trivial.c b/helgrind/tests/tc12_rwl_trivial.c index c9c83985f1..a84428e018 100644 --- a/helgrind/tests/tc12_rwl_trivial.c +++ b/helgrind/tests/tc12_rwl_trivial.c @@ -5,7 +5,7 @@ #define _GNU_SOURCE 1 #include -#include +#include "safe-pthread.h" #include /* Do trivial stuff with a reader-writer lock. */ diff --git a/helgrind/tests/tc12_rwl_trivial.stderr.exp b/helgrind/tests/tc12_rwl_trivial.stderr.exp index db33a0889e..76607e0428 100644 --- a/helgrind/tests/tc12_rwl_trivial.stderr.exp +++ b/helgrind/tests/tc12_rwl_trivial.stderr.exp @@ -8,6 +8,7 @@ Thread #x is the program's root thread Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc12_rwl_trivial.c:29) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris b/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris index aa16b571c1..04d2d90e7e 100644 --- a/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris +++ b/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris @@ -8,6 +8,7 @@ Thread #x is the program's root thread Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc12_rwl_trivial.c:29) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init (hg_intercepts.c:...) diff --git a/helgrind/tests/tc12_rwl_trivial.vgtest b/helgrind/tests/tc12_rwl_trivial.vgtest index fdcd6446eb..d0009d8145 100644 --- a/helgrind/tests/tc12_rwl_trivial.vgtest +++ b/helgrind/tests/tc12_rwl_trivial.vgtest @@ -1 +1,2 @@ +vgopts: --sigill-diagnostics=no prog: tc12_rwl_trivial diff --git a/helgrind/tests/tc20_verifywrap.c b/helgrind/tests/tc20_verifywrap.c index 899a285a73..3c976a2c3c 100644 --- a/helgrind/tests/tc20_verifywrap.c +++ b/helgrind/tests/tc20_verifywrap.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include "safe-pthread.h" #include #if !defined(__APPLE__) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp b/helgrind/tests/tc20_verifywrap.stderr.exp index 97c09f4e17..6d40ac61c7 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp +++ b/helgrind/tests/tc20_verifywrap.stderr.exp @@ -163,6 +163,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -180,6 +181,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -199,6 +201,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:227) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 index 8869b71d52..f10967317a 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 @@ -155,6 +155,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -169,6 +170,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 index e0e587bf2f..52f0b27f63 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 @@ -165,6 +165,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -179,6 +180,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -195,6 +197,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:227) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b index 01ccd00b9e..07f8db662c 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b @@ -165,6 +165,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -179,6 +180,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -195,6 +197,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:227) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x index d510cddd31..3f60f79457 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x @@ -165,6 +165,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -179,6 +180,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) @@ -195,6 +197,7 @@ Thread #x unlocked a not-locked lock at 0x........ Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:227) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris index b869be7f91..da7db08f60 100644 --- a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +++ b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris @@ -155,6 +155,7 @@ Thread #x's call to pthread_cond_timedwait failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:189) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init (hg_intercepts.c:...) @@ -180,6 +181,7 @@ Thread #x's call to pthread_rwlock_unlock failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:206) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init (hg_intercepts.c:...) @@ -207,6 +209,7 @@ Thread #x's call to pthread_rwlock_unlock failed Thread #x unlocked a not-locked lock at 0x........ at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... by 0x........: main (tc20_verifywrap.c:227) Lock at 0x........ was first observed at 0x........: pthread_rwlock_init (hg_intercepts.c:...) diff --git a/helgrind/tests/tc20_verifywrap.vgtest b/helgrind/tests/tc20_verifywrap.vgtest index 2accc94f43..0ee9c143d9 100644 --- a/helgrind/tests/tc20_verifywrap.vgtest +++ b/helgrind/tests/tc20_verifywrap.vgtest @@ -1,3 +1,3 @@ prereq: test -e tc20_verifywrap prog: tc20_verifywrap -vgopts: --read-var-info=yes +vgopts: --read-var-info=yes --sigill-diagnostics=no