|
From: <sv...@va...> - 2015-08-18 10:29:28
|
Author: tom
Date: Tue Aug 18 11:29:20 2015
New Revision: 15565
Log:
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.
Added:
trunk/helgrind/tests/safe-pthread.h (with props)
Modified:
trunk/drd/tests/tc12_rwl_trivial.stderr.exp
trunk/drd/tests/tc12_rwl_trivial.vgtest
trunk/helgrind/tests/tc12_rwl_trivial.c
trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp
trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris
trunk/helgrind/tests/tc12_rwl_trivial.vgtest
trunk/helgrind/tests/tc20_verifywrap.c
trunk/helgrind/tests/tc20_verifywrap.stderr.exp
trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18
trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32
trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b
trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x
trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris
trunk/helgrind/tests/tc20_verifywrap.vgtest
Modified: trunk/drd/tests/tc12_rwl_trivial.stderr.exp
==============================================================================
--- trunk/drd/tests/tc12_rwl_trivial.stderr.exp (original)
+++ trunk/drd/tests/tc12_rwl_trivial.stderr.exp Tue Aug 18 11:29:20 2015
@@ -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:?)
Modified: trunk/drd/tests/tc12_rwl_trivial.vgtest
==============================================================================
--- trunk/drd/tests/tc12_rwl_trivial.vgtest (original)
+++ trunk/drd/tests/tc12_rwl_trivial.vgtest Tue Aug 18 11:29:20 2015
@@ -1,2 +1,3 @@
prereq: ./supported_libpthread
+vgopts: --sigill-diagnostics=no
prog: ../../helgrind/tests/tc12_rwl_trivial
Added: trunk/helgrind/tests/safe-pthread.h
==============================================================================
--- trunk/helgrind/tests/safe-pthread.h (added)
+++ trunk/helgrind/tests/safe-pthread.h Tue Aug 18 11:29:20 2015
@@ -0,0 +1,56 @@
+#include <pthread.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+#include <assert.h>
+
+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
Modified: trunk/helgrind/tests/tc12_rwl_trivial.c
==============================================================================
--- trunk/helgrind/tests/tc12_rwl_trivial.c (original)
+++ trunk/helgrind/tests/tc12_rwl_trivial.c Tue Aug 18 11:29:20 2015
@@ -5,7 +5,7 @@
#define _GNU_SOURCE 1
#include <stdio.h>
-#include <pthread.h>
+#include "safe-pthread.h"
#include <assert.h>
/* Do trivial stuff with a reader-writer lock. */
Modified: trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp
==============================================================================
--- trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp (original)
+++ trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp Tue Aug 18 11:29:20 2015
@@ -8,6 +8,7 @@
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:...)
Modified: trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris
==============================================================================
--- trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris (original)
+++ trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris Tue Aug 18 11:29:20 2015
@@ -8,6 +8,7 @@
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:...)
Modified: trunk/helgrind/tests/tc12_rwl_trivial.vgtest
==============================================================================
--- trunk/helgrind/tests/tc12_rwl_trivial.vgtest (original)
+++ trunk/helgrind/tests/tc12_rwl_trivial.vgtest Tue Aug 18 11:29:20 2015
@@ -1 +1,2 @@
+vgopts: --sigill-diagnostics=no
prog: tc12_rwl_trivial
Modified: trunk/helgrind/tests/tc20_verifywrap.c
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.c (original)
+++ trunk/helgrind/tests/tc20_verifywrap.c Tue Aug 18 11:29:20 2015
@@ -15,7 +15,7 @@
#include <string.h>
#include <assert.h>
#include <unistd.h>
-#include <pthread.h>
+#include "safe-pthread.h"
#include <semaphore.h>
#if !defined(__APPLE__)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp Tue Aug 18 11:29:20 2015
@@ -163,6 +163,7 @@
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........
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........
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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 Tue Aug 18 11:29:20 2015
@@ -155,6 +155,7 @@
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........
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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 Tue Aug 18 11:29:20 2015
@@ -165,6 +165,7 @@
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........
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........
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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b Tue Aug 18 11:29:20 2015
@@ -165,6 +165,7 @@
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........
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........
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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x Tue Aug 18 11:29:20 2015
@@ -165,6 +165,7 @@
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........
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........
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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris (original)
+++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris Tue Aug 18 11:29:20 2015
@@ -155,6 +155,7 @@
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 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 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:...)
Modified: trunk/helgrind/tests/tc20_verifywrap.vgtest
==============================================================================
--- trunk/helgrind/tests/tc20_verifywrap.vgtest (original)
+++ trunk/helgrind/tests/tc20_verifywrap.vgtest Tue Aug 18 11:29:20 2015
@@ -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
|
|
From: Rhys K. <rhy...@gm...> - 2015-08-18 14:21:09
|
Seeing build failure with 'make check' on OS X as follows. Will get a
chance to look at fix within next day or so, unless others beat me to it.
depbase=`echo tc12_rwl_trivial.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DHAVE_CONFIG_H -I. -I../.. -I../.. -I../../include
-I../../coregrind -I../../include -I../../VEX/pub -I../../VEX/pub
-DVGA_amd64=1 -DVGO_darwin=1 -DVGP_amd64_darwin=1
-DVGPV_amd64_darwin_vanilla=1 -DVGA_SEC_x86=1 -DVGP_SEC_amd64_darwin=1
-Winline -Wall -Wshadow -Wno-long-long -g -fno-stack-protector
-Wno-format-extra-args -Wno-literal-range
-Wno-tautological-constant-out-of-range-compare -Wno-self-assign
-Wno-string-plus-int -Wno-uninitialized -Wno-unused-value -arch x86_64
-MT tc12_rwl_trivial.o -MD -MP -MF $depbase.Tpo -c -o tc12_rwl_trivial.o
tc12_rwl_trivial.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from tc12_rwl_trivial.c:8:
./safe-pthread.h:29:19: error: token is not a valid binary operator in a
preprocessor subexpression
#if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) )
~~~~~~~~~~~~~~^
1 error generated.
On 18 August 2015 at 20:29, <sv...@va...> wrote:
> Author: tom
> Date: Tue Aug 18 11:29:20 2015
> New Revision: 15565
>
> Log:
> 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.
>
> Added:
> trunk/helgrind/tests/safe-pthread.h (with props)
> Modified:
> trunk/drd/tests/tc12_rwl_trivial.stderr.exp
> trunk/drd/tests/tc12_rwl_trivial.vgtest
> trunk/helgrind/tests/tc12_rwl_trivial.c
> trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp
> trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris
> trunk/helgrind/tests/tc12_rwl_trivial.vgtest
> trunk/helgrind/tests/tc20_verifywrap.c
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x
> trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris
> trunk/helgrind/tests/tc20_verifywrap.vgtest
>
> Modified: trunk/drd/tests/tc12_rwl_trivial.stderr.exp
>
> ==============================================================================
> --- trunk/drd/tests/tc12_rwl_trivial.stderr.exp (original)
> +++ trunk/drd/tests/tc12_rwl_trivial.stderr.exp Tue Aug 18 11:29:20 2015
> @@ -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:?)
>
> Modified: trunk/drd/tests/tc12_rwl_trivial.vgtest
>
> ==============================================================================
> --- trunk/drd/tests/tc12_rwl_trivial.vgtest (original)
> +++ trunk/drd/tests/tc12_rwl_trivial.vgtest Tue Aug 18 11:29:20 2015
> @@ -1,2 +1,3 @@
> prereq: ./supported_libpthread
> +vgopts: --sigill-diagnostics=no
> prog: ../../helgrind/tests/tc12_rwl_trivial
>
> Added: trunk/helgrind/tests/safe-pthread.h
>
> ==============================================================================
> --- trunk/helgrind/tests/safe-pthread.h (added)
> +++ trunk/helgrind/tests/safe-pthread.h Tue Aug 18 11:29:20 2015
> @@ -0,0 +1,56 @@
> +#include <pthread.h>
> +#include <signal.h>
> +#include <setjmp.h>
> +#include <errno.h>
> +#include <assert.h>
> +
> +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
>
> Modified: trunk/helgrind/tests/tc12_rwl_trivial.c
>
> ==============================================================================
> --- trunk/helgrind/tests/tc12_rwl_trivial.c (original)
> +++ trunk/helgrind/tests/tc12_rwl_trivial.c Tue Aug 18 11:29:20 2015
> @@ -5,7 +5,7 @@
> #define _GNU_SOURCE 1
>
> #include <stdio.h>
> -#include <pthread.h>
> +#include "safe-pthread.h"
> #include <assert.h>
>
> /* Do trivial stuff with a reader-writer lock. */
>
> Modified: trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp
>
> ==============================================================================
> --- trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp (original)
> +++ trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp Tue Aug 18 11:29:20
> 2015
> @@ -8,6 +8,7 @@
> 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:...)
>
> Modified: trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris
>
> ==============================================================================
> --- trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris (original)
> +++ trunk/helgrind/tests/tc12_rwl_trivial.stderr.exp-solaris Tue Aug 18
> 11:29:20 2015
> @@ -8,6 +8,7 @@
> 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:...)
>
> Modified: trunk/helgrind/tests/tc12_rwl_trivial.vgtest
>
> ==============================================================================
> --- trunk/helgrind/tests/tc12_rwl_trivial.vgtest (original)
> +++ trunk/helgrind/tests/tc12_rwl_trivial.vgtest Tue Aug 18 11:29:20 2015
> @@ -1 +1,2 @@
> +vgopts: --sigill-diagnostics=no
> prog: tc12_rwl_trivial
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.c
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.c (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.c Tue Aug 18 11:29:20 2015
> @@ -15,7 +15,7 @@
> #include <string.h>
> #include <assert.h>
> #include <unistd.h>
> -#include <pthread.h>
> +#include "safe-pthread.h"
> #include <semaphore.h>
>
> #if !defined(__APPLE__)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp Tue Aug 18 11:29:20
> 2015
> @@ -163,6 +163,7 @@
> 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........
> 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........
> 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 Tue Aug 18
> 11:29:20 2015
> @@ -155,6 +155,7 @@
> 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........
> 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32 Tue Aug 18
> 11:29:20 2015
> @@ -165,6 +165,7 @@
> 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........
> 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........
> 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-mips32-b Tue Aug 18
> 11:29:20 2015
> @@ -165,6 +165,7 @@
> 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........
> 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........
> 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-s390x Tue Aug 18
> 11:29:20 2015
> @@ -165,6 +165,7 @@
> 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........
> 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........
> 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.stderr.exp-solaris Tue Aug 18
> 11:29:20 2015
> @@ -155,6 +155,7 @@
> 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 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 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:...)
>
> Modified: trunk/helgrind/tests/tc20_verifywrap.vgtest
>
> ==============================================================================
> --- trunk/helgrind/tests/tc20_verifywrap.vgtest (original)
> +++ trunk/helgrind/tests/tc20_verifywrap.vgtest Tue Aug 18 11:29:20 2015
> @@ -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
>
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
>
|
|
From: Julian S. <js...@ac...> - 2015-08-18 14:34:14
|
On 18/08/15 16:21, Rhys Kidd wrote:
> Seeing build failure with 'make check' on OS X as follows. Will get a
> ./safe-pthread.h:29:19: error: token is not a valid binary operator in a
> preprocessor subexpression
> #if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) )
> ~~~~~~~~~~~~~~^
Yes, I imagine __GLIBC_PREREQ doesn't exist on OS X. What about this?
#if defined(__GLIBC_PREREQ) \
&& __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) )
Will that fix it?
J
|
|
From: Tom H. <to...@co...> - 2015-08-18 14:37:33
|
On 18/08/15 15:34, Julian Seward wrote: > On 18/08/15 16:21, Rhys Kidd wrote: >> Seeing build failure with 'make check' on OS X as follows. Will get a > >> ./safe-pthread.h:29:19: error: token is not a valid binary operator in a >> preprocessor subexpression >> #if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) ) >> ~~~~~~~~~~~~~~^ > > Yes, I imagine __GLIBC_PREREQ doesn't exist on OS X. What about this? > > #if defined(__GLIBC_PREREQ) \ > && __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) ) > > Will that fix it? Should do. Sorry, stole that from the main tc20 code without paying attention to all the humps it jumped through to define it on other platforms. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Matthias S. <zz...@ge...> - 2015-08-24 18:28:54
|
Am 23.08.2015 um 11:13 schrieb Tom Hughes: > On 22/08/15 06:51, Matthias Schwarzott wrote: >> Am 22.08.2015 um 01:02 schrieb Tom Hughes: >> >>> There shouldn't be a second SIGILL signal. >> >> For me tc20_verifywrap.c triggers SIGILL in three locations: >> * tc20_verifywrap.c:189 (pthread_rwlock_unlock after init) >> * tc20_verifywrap.c:206 (double pthread_rwlock_unlock) >> * tc20_verifywrap.c:227 (three pthread_rwlock_unlock after two >> pthread_rwlock_rdlock) >> >> So technically there should be three SIGILL signals. > > Yes but each one is from a separate call to pthread_rwlock_unlock that > installs the signal handler before it starts and removes it afterwards. > > So there is no question of SA_NODEFER being needed because we are not > getting a SIGLLL while still handling the previous one. We are getting > one, handling it, then getting a second one, handling it, and then > getting a thired one. > >>> When SIGILL is caught we jump >>> out and restore the original handler. >> Yes, but we do not restore the signal mask. And if SA_NODEFER is not >> set, the signal will stay blocked afterwards. And we also do not call >> sigmask/sigblock/sigsetmask. >> >> From man sigaction: >> sa_mask specifies a mask of signals which should be blocked >> (i.e., added to the signal mask of the thread in which the signal >> handler >> is invoked) during execution of the signal handler. In >> addition, the signal which triggered the handler will be blocked, >> unless the >> SA_NODEFER flag is used. > > That mask is only applied while the signal is being handled though, and > should be removed afterwards. > > I have to admit that I'm not quite sure how (or if?) that happens when > you jump out of the handler... So maybe that is the real problem here in > which case the correct solution is likely sigsetjmp/siglongjmp. I think it just does not happen. Normally the return address of the signal handler points to a signal trampoline that cleans up and then calls sigreturn. This function restores the signal mask. Calling longjmp out of the signal handler skips this cleanup part. > > The trouble is that the current solution somehow seems to work for me in > that tc20 survives all three unlocks and then hits the abort. > Hmm, I have no clue. > Can you try changing setjmp to sigsetjmp (with a non-zero second > argument) and longjmp to siglongjmp, and see if that helps? > Yes, that fixes the issue. Regards Matthias |
|
From: Tom H. <to...@co...> - 2015-08-24 19:11:24
|
On 24/08/15 19:28, Matthias Schwarzott wrote: > Am 23.08.2015 um 11:13 schrieb Tom Hughes: > >> Can you try changing setjmp to sigsetjmp (with a non-zero second >> argument) and longjmp to siglongjmp, and see if that helps? >> > Yes, that fixes the issue. Thanks for confirming that. Committed as r15587. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Mark W. <mj...@re...> - 2015-08-18 17:08:32
|
On Tue, 2015-08-18 at 15:37 +0100, Tom Hughes wrote:
> On 18/08/15 15:34, Julian Seward wrote:
> > On 18/08/15 16:21, Rhys Kidd wrote:
> >> Seeing build failure with 'make check' on OS X as follows. Will get a
> >
> >> ./safe-pthread.h:29:19: error: token is not a valid binary operator in a
> >> preprocessor subexpression
> >> #if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) )
> >> ~~~~~~~~~~~~~~^
> >
> > Yes, I imagine __GLIBC_PREREQ doesn't exist on OS X. What about this?
> >
> > #if defined(__GLIBC_PREREQ) \
> > && __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) )
> >
> > Will that fix it?
>
> Should do. Sorry, stole that from the main tc20 code without paying
> attention to all the humps it jumped through to define it on other
> platforms.
Do we really need the #if?
Can't we just always install the sigill handler?
Currently the test will fail on glibc < 2.20 since the backtrace looks
slightly different:
--- tc12_rwl_trivial.stderr.exp 2015-08-18 15:25:07.011729981 +0200
+++ tc12_rwl_trivial.stderr.out 2015-08-18 15:37:12.187446390 +0200
@@ -1,7 +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........: safe_pthread_rwlock_unlock (safe-pthread.h:52)
by 0x........: main (tc12_rwl_trivial.c:29)
rwlock 0x........ was first observed at:
at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?)
If we just always installed the handler then the line would always be
the same.
Cheers,
M ark
|
|
From: Mark W. <mj...@re...> - 2015-08-24 20:19:10
Attachments:
0001-safe-sem_post-handler.patch
|
I hoped to fix the SIGABRT issue with tc18 and tc20 for sem_post in a similar way. See attached. It does "fix" the tc18 case, but not the tc20 case. Since hellgrind doesn't actually see the failure now it doesn't report anything. Which works for tc18 since there is an alternate exp file with that result (silent bad sem_post), but tc20 doesn't have an alternative where there is no EINVAL so it still reports an error. But at least not an abort, but a missing EINVAL. I do think glibc not detecting a bad semaphore might be allowed, so maybe we could just add an alternative tc20.exp that just doesn't see the EINVAL. Or would that be too much "cheating"? Cheers, Mark |
|
From: Mark W. <mj...@re...> - 2015-09-01 22:23:28
|
On Mon, Aug 24, 2015 at 10:19:01PM +0200, Mark Wielaard wrote: > I hoped to fix the SIGABRT issue with tc18 and tc20 for sem_post > in a similar way. See attached. > > It does "fix" the tc18 case, but not the tc20 case. > > Since hellgrind doesn't actually see the failure now it doesn't report > anything. Which works for tc18 since there is an alternate exp file with > that result (silent bad sem_post), but tc20 doesn't have an alternative > where there is no EINVAL so it still reports an error. But at least not > an abort, but a missing EINVAL. > > I do think glibc not detecting a bad semaphore might be allowed, so > maybe we could just add an alternative tc20.exp that just doesn't see > the EINVAL. Or would that be too much "cheating"? So if nobody objects I would like to push the attached patch. Cheers, Mark |
|
From: Mark W. <mj...@re...> - 2015-09-04 09:43:07
|
On Wed, 2015-09-02 at 00:23 +0200, Mark Wielaard wrote: > On Mon, Aug 24, 2015 at 10:19:01PM +0200, Mark Wielaard wrote: > > I hoped to fix the SIGABRT issue with tc18 and tc20 for sem_post > > in a similar way. See attached. > > > > It does "fix" the tc18 case, but not the tc20 case. > > > > Since hellgrind doesn't actually see the failure now it doesn't report > > anything. Which works for tc18 since there is an alternate exp file with > > that result (silent bad sem_post), but tc20 doesn't have an alternative > > where there is no EINVAL so it still reports an error. But at least not > > an abort, but a missing EINVAL. > > > > I do think glibc not detecting a bad semaphore might be allowed, so > > maybe we could just add an alternative tc20.exp that just doesn't see > > the EINVAL. Or would that be too much "cheating"? > > So if nobody objects I would like to push the attached patch. Since nobody loudly objected I have now pushed this as valgrind svn r15620. Please yell and scream if this breaks things for anybody. Thanks, Mark |
|
From: Tom H. <to...@co...> - 2015-08-18 17:29:00
|
On 18/08/15 18:08, Mark Wielaard wrote: > On Tue, 2015-08-18 at 15:37 +0100, Tom Hughes wrote: >> On 18/08/15 15:34, Julian Seward wrote: >>> On 18/08/15 16:21, Rhys Kidd wrote: >>>> Seeing build failure with 'make check' on OS X as follows. Will get a >>> >>>> ./safe-pthread.h:29:19: error: token is not a valid binary operator in a >>>> preprocessor subexpression >>>> #if __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) ) >>>> ~~~~~~~~~~~~~~^ >>> >>> Yes, I imagine __GLIBC_PREREQ doesn't exist on OS X. What about this? >>> >>> #if defined(__GLIBC_PREREQ) \ >>> && __GLIBC_PREREQ(2,20) && ( defined(__i386__) || defined(__x86_64__) ) >>> >>> Will that fix it? >> >> Should do. Sorry, stole that from the main tc20 code without paying >> attention to all the humps it jumped through to define it on other >> platforms. > > Do we really need the #if? > Can't we just always install the sigill handler? That would work as well. I was just being conservative... Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Matthias S. <zz...@ge...> - 2015-08-21 06:19:31
|
Hi!
I tested it now with current trunk (revision 15574).
My system is gentoo using an amd64 cpu - Intel Core i3-4160.
The glibc is 2.21 (ebuild revision r1).
The status is like thisfor helgrind and drd:
$ perl tests/vg_regtest helgrind/ drd/
== 181 tests, 4 stderr failures, 0 stdout failures, 0 stderrB failures,
0 stdoutB failures, 0 post failures ==
helgrind/tests/stackteardown (stderr)
helgrind/tests/tc18_semabuse (stderr)
helgrind/tests/tc20_verifywrap (stderr)
drd/tests/tc18_semabuse (stderr)
The failures:
I don't know the reason for stackteardown (it only fails sometimes when
I try only this one).
For tc18_semabuse and tc20_verifywrap the reason is similar.
tc18_semabuse gets a SIGABRT at this callstack:
#0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:55
#1 0x00007ffff785874a in __GI_abort () at abort.c:89
#2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>,
processes_to_wake=1, futex=<optimized out>) at sem_post.c:50
#3 __new_sem_post (sem=<optimized out>) at sem_post.c:81
#4 0x0000000000400976 in main () at tc18_semabuse.c:40
With original trunk tc20_verifywrap is killed with the second signal
SIGILL that is delivered to it.
#0 __GI___pthread_rwlock_unlock (rwlock=0x7fffffffd780) at
pthread_rwlock_unlock.c:34
#1 0x0000000000401235 in safe_pthread_rwlock_unlock
(rwlock=0x7fffffffd780) at safe-pthread.h:58
#2 0x000000000040199e in main () at tc20_verifywrap.c:206
By setting the flag SA_NODEFER for the signal handlers, it can be made
to catch all signals and not only the first:
--- a/helgrind/tests/safe-pthread.h
+++ b/helgrind/tests/safe-pthread.h
@@ -43,14 +43,14 @@ static int safe_pthread_rwlock_unlock(
pthread_rwlock_t *rwlock ) {
sa_ill.sa_handler = NULL;
sa_ill.sa_sigaction = sigill_handler;
sigemptyset( &sa_ill.sa_mask );
- sa_ill.sa_flags = SA_SIGINFO;
+ sa_ill.sa_flags = SA_SIGINFO | SA_NODEFER;
sigaction( SIGILL, &sa_ill, &oldsa_ill );
sa_segv.sa_handler = NULL;
sa_segv.sa_sigaction = segv_handler;
sigemptyset( &sa_segv.sa_mask );
- sa_segv.sa_flags = SA_SIGINFO;
+ sa_segv.sa_flags = SA_SIGINFO | SA_NODEFER;
sigaction( SIGSEGV, &sa_segv, &oldsa_segv );
Now it dies the same way as tc18_semabuse:
#0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:55
#1 0x00007ffff785874a in __GI_abort () at abort.c:89
#2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>,
processes_to_wake=1, futex=<optimized out>) at sem_post.c:50
#3 __new_sem_post (sem=<optimized out>) at sem_post.c:81
#4 0x0000000000401cb5 in main () at tc20_verifywrap.c:265
For deeper analysis, here is the end of the strace for tc18_semabuse:
clone(child_stack=0x7f8fa5e4aff0,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,
parent_tidptr=0x7f8fa5e4b9d0, tls=0x7f8fa5e4b700,
child_tidptr=0x7f8fa5e4b9d0) = 13522
futex(0x7ffdc5d743d0, 0x555555d4 /* FUTEX_??? */, 1) = -1 ENOSYS
(Function not implemented)
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
tgkill(13521, 13521, SIGABRT) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=13521,
si_uid=1003} ---
+++ killed by SIGABRT +++
Regards
Matthias
|
|
From: Tom H. <to...@co...> - 2015-08-21 08:06:10
|
On 21/08/15 07:19, Matthias Schwarzott wrote:
> For tc18_semabuse and tc20_verifywrap the reason is similar.
>
> tc18_semabuse gets a SIGABRT at this callstack:
> #0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at
> ../sysdeps/unix/sysv/linux/raise.c:55
> #1 0x00007ffff785874a in __GI_abort () at abort.c:89
> #2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>,
> processes_to_wake=1, futex=<optimized out>) at sem_post.c:50
> #3 __new_sem_post (sem=<optimized out>) at sem_post.c:81
> #4 0x0000000000400976 in main () at tc18_semabuse.c:40
Yes we're aware that both tc18 and tc20 produce this, and I know the
cause, we just haven't come up with a good solution yet.
> With original trunk tc20_verifywrap is killed with the second signal
> SIGILL that is delivered to it.
Actually the SIGILL is before the SIGABRT and you're not seeing it now
precisely because we now catch and ignore it.
> #0 __GI___pthread_rwlock_unlock (rwlock=0x7fffffffd780) at
> pthread_rwlock_unlock.c:34
> #1 0x0000000000401235 in safe_pthread_rwlock_unlock
> (rwlock=0x7fffffffd780) at safe-pthread.h:58
> #2 0x000000000040199e in main () at tc20_verifywrap.c:206
>
> By setting the flag SA_NODEFER for the signal handlers, it can be made
> to catch all signals and not only the first:
Err, not really, and in any case where
> clone(child_stack=0x7f8fa5e4aff0,
> flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,
> parent_tidptr=0x7f8fa5e4b9d0, tls=0x7f8fa5e4b700,
> child_tidptr=0x7f8fa5e4b9d0) = 13522
> futex(0x7ffdc5d743d0, 0x555555d4 /* FUTEX_??? */, 1) = -1 ENOSYS
> (Function not implemented)
> rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
> tgkill(13521, 13521, SIGABRT) = 0
> --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=13521,
> si_uid=1003} ---
> +++ killed by SIGABRT +++
Exactly. The problem is that we memset a semaphore structure with 0x55
to create an "invalid" semaphore, but glibc now uses one of those bytes
directly now to or into the futex opcode, which gives an invalid futex
call, and glibc then aborts on the ENOSYS return.
Tom
--
Tom Hughes (to...@co...)
http://compton.nu/
|
|
From: Matthias S. <zz...@ge...> - 2015-08-21 22:11:06
Attachments:
0001-fix-catching-signal-a-second-time.patch
|
Am 21.08.2015 um 10:05 schrieb Tom Hughes: > On 21/08/15 07:19, Matthias Schwarzott wrote: > >> For tc18_semabuse and tc20_verifywrap the reason is similar. >> >> tc18_semabuse gets a SIGABRT at this callstack: >> #0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at >> ../sysdeps/unix/sysv/linux/raise.c:55 >> #1 0x00007ffff785874a in __GI_abort () at abort.c:89 >> #2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>, >> processes_to_wake=1, futex=<optimized out>) at sem_post.c:50 >> #3 __new_sem_post (sem=<optimized out>) at sem_post.c:81 >> #4 0x0000000000400976 in main () at tc18_semabuse.c:40 > > Yes we're aware that both tc18 and tc20 produce this, and I know the > cause, we just haven't come up with a good solution yet. > >> With original trunk tc20_verifywrap is killed with the second signal >> SIGILL that is delivered to it. > > Actually the SIGILL is before the SIGABRT and you're not seeing it now > precisely because we now catch and ignore it. > At least it should be like this. For me this test is always killed by the second SIGILL signal. If the signal is sent more than once, it must be unblocked after the first. Either call some sigblock function at sighandler setup or inside sighandler or set the flag SA_NODEFER. This is contained in the attached patch. Regards Matthias |
|
From: Tom H. <to...@co...> - 2015-08-21 23:03:28
|
On 21/08/15 23:10, Matthias Schwarzott wrote: > Am 21.08.2015 um 10:05 schrieb Tom Hughes: >> On 21/08/15 07:19, Matthias Schwarzott wrote: >> >>> For tc18_semabuse and tc20_verifywrap the reason is similar. >>> >>> tc18_semabuse gets a SIGABRT at this callstack: >>> #0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at >>> ../sysdeps/unix/sysv/linux/raise.c:55 >>> #1 0x00007ffff785874a in __GI_abort () at abort.c:89 >>> #2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>, >>> processes_to_wake=1, futex=<optimized out>) at sem_post.c:50 >>> #3 __new_sem_post (sem=<optimized out>) at sem_post.c:81 >>> #4 0x0000000000400976 in main () at tc18_semabuse.c:40 >> >> Yes we're aware that both tc18 and tc20 produce this, and I know the >> cause, we just haven't come up with a good solution yet. >> >>> With original trunk tc20_verifywrap is killed with the second signal >>> SIGILL that is delivered to it. >> >> Actually the SIGILL is before the SIGABRT and you're not seeing it now >> precisely because we now catch and ignore it. >> > At least it should be like this. > For me this test is always killed by the second SIGILL signal. > > If the signal is sent more than once, it must be unblocked after the > first. Either call some sigblock function at sighandler setup or inside > sighandler or set the flag SA_NODEFER. > This is contained in the attached patch. There shouldn't be a second SIGILL signal. When SIGILL is caught we jump out and restore the original handler. The other signal you quoted is SIGABRT not SIGILL and happens much later when we don't even have the handler installed. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Matthias S. <zz...@ge...> - 2015-08-22 05:51:24
|
Am 22.08.2015 um 01:02 schrieb Tom Hughes:
> On 21/08/15 23:10, Matthias Schwarzott wrote:
>> Am 21.08.2015 um 10:05 schrieb Tom Hughes:
>>> On 21/08/15 07:19, Matthias Schwarzott wrote:
>>>
>>>> For tc18_semabuse and tc20_verifywrap the reason is similar.
>>>>
>>>> tc18_semabuse gets a SIGABRT at this callstack:
>>>> #0 0x00007ffff78573b7 in __GI_raise (sig=sig@entry=6) at
>>>> ../sysdeps/unix/sysv/linux/raise.c:55
>>>> #1 0x00007ffff785874a in __GI_abort () at abort.c:89
>>>> #2 0x00007ffff7bcdf77 in futex_wake (private=<optimized out>,
>>>> processes_to_wake=1, futex=<optimized out>) at sem_post.c:50
>>>> #3 __new_sem_post (sem=<optimized out>) at sem_post.c:81
>>>> #4 0x0000000000400976 in main () at tc18_semabuse.c:40
>>>
>>> Yes we're aware that both tc18 and tc20 produce this, and I know the
>>> cause, we just haven't come up with a good solution yet.
>>>
>>>> With original trunk tc20_verifywrap is killed with the second signal
>>>> SIGILL that is delivered to it.
>>>
>>> Actually the SIGILL is before the SIGABRT and you're not seeing it now
>>> precisely because we now catch and ignore it.
>>>
>> At least it should be like this.
>> For me this test is always killed by the second SIGILL signal.
>>
>> If the signal is sent more than once, it must be unblocked after the
>> first. Either call some sigblock function at sighandler setup or inside
>> sighandler or set the flag SA_NODEFER.
>> This is contained in the attached patch.
>
> There shouldn't be a second SIGILL signal.
For me tc20_verifywrap.c triggers SIGILL in three locations:
* tc20_verifywrap.c:189 (pthread_rwlock_unlock after init)
* tc20_verifywrap.c:206 (double pthread_rwlock_unlock)
* tc20_verifywrap.c:227 (three pthread_rwlock_unlock after two
pthread_rwlock_rdlock)
So technically there should be three SIGILL signals.
> When SIGILL is caught we jump
> out and restore the original handler.
Yes, but we do not restore the signal mask. And if SA_NODEFER is not
set, the signal will stay blocked afterwards. And we also do not call
sigmask/sigblock/sigsetmask.
>From man sigaction:
sa_mask specifies a mask of signals which should be blocked
(i.e., added to the signal mask of the thread in which the signal handler
is invoked) during execution of the signal handler. In
addition, the signal which triggered the handler will be blocked, unless the
SA_NODEFER flag is used.
>
> The other signal you quoted is SIGABRT not SIGILL and happens much later
> when we don't even have the handler installed.
>
Yes, and I want that the code is at least able to reach the point where
the SIGABRT is sent.
Matthias
|
|
From: Tom H. <to...@co...> - 2015-08-23 09:13:53
|
On 22/08/15 06:51, Matthias Schwarzott wrote: > Am 22.08.2015 um 01:02 schrieb Tom Hughes: > >> There shouldn't be a second SIGILL signal. > > For me tc20_verifywrap.c triggers SIGILL in three locations: > * tc20_verifywrap.c:189 (pthread_rwlock_unlock after init) > * tc20_verifywrap.c:206 (double pthread_rwlock_unlock) > * tc20_verifywrap.c:227 (three pthread_rwlock_unlock after two > pthread_rwlock_rdlock) > > So technically there should be three SIGILL signals. Yes but each one is from a separate call to pthread_rwlock_unlock that installs the signal handler before it starts and removes it afterwards. So there is no question of SA_NODEFER being needed because we are not getting a SIGLLL while still handling the previous one. We are getting one, handling it, then getting a second one, handling it, and then getting a thired one. >> When SIGILL is caught we jump >> out and restore the original handler. > Yes, but we do not restore the signal mask. And if SA_NODEFER is not > set, the signal will stay blocked afterwards. And we also do not call > sigmask/sigblock/sigsetmask. > > From man sigaction: > sa_mask specifies a mask of signals which should be blocked > (i.e., added to the signal mask of the thread in which the signal handler > is invoked) during execution of the signal handler. In > addition, the signal which triggered the handler will be blocked, unless the > SA_NODEFER flag is used. That mask is only applied while the signal is being handled though, and should be removed afterwards. I have to admit that I'm not quite sure how (or if?) that happens when you jump out of the handler... So maybe that is the real problem here in which case the correct solution is likely sigsetjmp/siglongjmp. The trouble is that the current solution somehow seems to work for me in that tc20 survives all three unlocks and then hits the abort. Can you try changing setjmp to sigsetjmp (with a non-zero second argument) and longjmp to siglongjmp, and see if that helps? Tom -- Tom Hughes (to...@co...) http://compton.nu/ |