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:41)
+ by 0x........: safe_pthread_rwlock_unlock (safe-pthread.h:58)
by 0x........: main (tc12_rwl_trivial.c:29)
rwlock 0x........ was first observed at:
at 0x........: pthread_rwlock_init (drd_pthread_intercepts.c:?)
longjmp( env, EPERM );
}
+/*
+ * Same as above, but in case we do recognize the xend,
+ * but detect it is invalid (used outside a transaction)
+ * and generate a segv. Unfortunately then si_addr is,
+ * just zero, so we cannot add an assert/sanity check.
+ */
+static void segv_handler( int signum, siginfo_t *siginfo, void *sigcontext ) {
+ longjmp( env, EPERM );
+}
+
/*
* Wrapper for pthread_rwlock_unlock which may execute xend
* unconditionally when used on a lock that is not locked.
* glibc normally does - error reporting is optional.
*/
static int safe_pthread_rwlock_unlock( pthread_rwlock_t *rwlock ) {
- struct sigaction sa;
- struct sigaction oldsa;
+ struct sigaction sa_ill, sa_segv;
+ struct sigaction oldsa_ill, oldsa_segv;
int r;
- sa.sa_handler = NULL;
- sa.sa_sigaction = sigill_handler;
- sigemptyset( &sa.sa_mask );
- sa.sa_flags = SA_SIGINFO;
+ sa_ill.sa_handler = NULL;
+ sa_ill.sa_sigaction = sigill_handler;
+ sigemptyset( &sa_ill.sa_mask );
+ sa_ill.sa_flags = SA_SIGINFO;
- sigaction( SIGILL, &sa, &oldsa );
+ 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;
+
+ sigaction( SIGSEGV, &sa_segv, &oldsa_segv );
if ( ( r = setjmp( env ) ) == 0 ) {
r = pthread_rwlock_unlock( rwlock );
r = 0;
}
- sigaction( SIGILL, &oldsa, NULL );
+ sigaction( SIGILL, &oldsa_ill, NULL );
+ sigaction( SIGSEGV, &oldsa_segv, NULL );
return r;
}