|
From: <sv...@va...> - 2009-07-27 16:04:02
|
Author: bart
Date: 2009-07-27 17:03:51 +0100 (Mon, 27 Jul 2009)
New Revision: 10638
Log:
Implemented type checking for reader-writer synchronization
objects: complain upon attempts to use a POSIX rwlock where a
user-defined rwlock is expected and vice versa.
Added:
trunk/drd/tests/rwlock_type_checking.c
trunk/drd/tests/rwlock_type_checking.stderr.exp
trunk/drd/tests/rwlock_type_checking.vgtest
Modified:
trunk/drd/drd_clientobj.h
trunk/drd/drd_rwlock.c
trunk/drd/tests/
trunk/drd/tests/Makefile.am
Modified: trunk/drd/drd_clientobj.h
===================================================================
--- trunk/drd/drd_clientobj.h 2009-07-27 14:48:06 UTC (rev 10637)
+++ trunk/drd/drd_clientobj.h 2009-07-27 16:03:51 UTC (rev 10638)
@@ -124,6 +124,7 @@
void (*cleanup)(union drd_clientobj*);
void (*delete_thread)(union drd_clientobj*, DrdThreadId);
ExeContext* first_observed_at;
+ RwLockT rwlock_type;
OSet* thread_info;
ULong acquiry_time_ms;
ExeContext* acquired_at;
Modified: trunk/drd/drd_rwlock.c
===================================================================
--- trunk/drd/drd_rwlock.c 2009-07-27 14:48:06 UTC (rev 10637)
+++ trunk/drd/drd_rwlock.c 2009-07-27 16:03:51 UTC (rev 10638)
@@ -194,9 +194,40 @@
DRD_(vc_cleanup)(&old_vc);
}
+/**
+ * Compare the type of the rwlock specified at initialization time with
+ * the type passed as an argument, and complain if these two types do not
+ * match.
+ */
+static Bool drd_rwlock_check_type(struct rwlock_info* const p,
+ const RwLockT rwlock_type)
+{
+ tl_assert(p);
+ /* The code below has to be updated if additional rwlock types are added. */
+ tl_assert(rwlock_type == pthread_rwlock || rwlock_type == user_rwlock);
+ tl_assert(p->rwlock_type == pthread_rwlock || p->rwlock_type == user_rwlock);
+
+ if (p->rwlock_type == rwlock_type)
+ return True;
+
+ {
+ RwlockErrInfo REI = { DRD_(thread_get_running_tid)(), p->a1 };
+ VG_(maybe_record_error)
+ (VG_(get_running_tid)(),
+ RwlockErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ rwlock_type == pthread_rwlock
+ ? "Attempt to use a user-defined rwlock as a POSIX rwlock"
+ : "Attempt to use a POSIX rwlock as a user-defined rwlock",
+ &REI);
+ }
+ return False;
+}
+
/** Initialize the rwlock_info data structure *p. */
static
-void DRD_(rwlock_initialize)(struct rwlock_info* const p, const Addr rwlock)
+void DRD_(rwlock_initialize)(struct rwlock_info* const p, const Addr rwlock,
+ const RwLockT rwlock_type)
{
tl_assert(rwlock != 0);
tl_assert(p->a1 == rwlock);
@@ -205,6 +236,7 @@
p->cleanup = (void(*)(DrdClientobj*))rwlock_cleanup;
p->delete_thread
= (void(*)(DrdClientobj*, DrdThreadId))rwlock_delete_thread;
+ p->rwlock_type = rwlock_type;
p->thread_info = VG_(OSetGen_Create)(
0, 0, VG_(malloc), "drd.rwlock.ri.1", VG_(free));
p->acquiry_time_ms = 0;
@@ -248,14 +280,17 @@
static
struct rwlock_info*
-DRD_(rwlock_get_or_allocate)(const Addr rwlock)
+DRD_(rwlock_get_or_allocate)(const Addr rwlock, const RwLockT rwlock_type)
{
struct rwlock_info* p;
tl_assert(offsetof(DrdClientobj, rwlock) == 0);
p = &(DRD_(clientobj_get)(rwlock, ClientRwlock)->rwlock);
if (p)
+ {
+ drd_rwlock_check_type(p, rwlock_type);
return p;
+ }
if (DRD_(clientobj_present)(rwlock, rwlock + 1))
{
@@ -269,7 +304,7 @@
}
p = &(DRD_(clientobj_add)(rwlock, ClientRwlock)->rwlock);
- DRD_(rwlock_initialize)(p, rwlock);
+ DRD_(rwlock_initialize)(p, rwlock, rwlock_type);
return p;
}
@@ -307,7 +342,7 @@
return p;
}
- p = DRD_(rwlock_get_or_allocate)(rwlock);
+ p = DRD_(rwlock_get_or_allocate)(rwlock, rwlock_type);
return p;
}
@@ -350,7 +385,7 @@
rwlock);
}
- p = DRD_(rwlock_get_or_allocate)(rwlock);
+ p = DRD_(rwlock_get_or_allocate)(rwlock, rwlock_type);
tl_assert(p);
if (DRD_(rwlock_is_wrlocked_by)(p, DRD_(thread_get_running_tid)()))
@@ -422,7 +457,7 @@
}
if (p == 0)
- p = DRD_(rwlock_get_or_allocate)(rwlock);
+ p = DRD_(rwlock_get_or_allocate)(rwlock, rwlock_type);
tl_assert(p);
Property changes on: trunk/drd/tests
___________________________________________________________________
Name: svn:ignore
- *.dSYM
*.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
annotate_rwlock
atomic_var
bar_bad
bar_trivial
boost_thread
circular_buffer
custom_alloc
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
Makefile
Makefile.in
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
omp_printf
pth_barrier
pth_barrier_race
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cleanup_handler
pth_cond_race
pth_create_chain
pth_create_glibc_2_0
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_mutex_reinit
pth_process_shared_mutex
pth_spinlock
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
sem_as_mutex
sem_open
sigalrm
tc01_simple_race
tc02_simple_tls
tc03_re_excl
tc04_free_lock
tc05_simple_race
tc06_two_races
tc07_hbl1
tc08_hbl2
tc09_bad_unlock
tc10_rec_lock
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
thread_name
trylock
tsan_unittest
unit_bitmap
unit_vc
vg_regtest.tmp*
+ *.dSYM
*.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
annotate_rwlock
atomic_var
bar_bad
bar_trivial
boost_thread
circular_buffer
custom_alloc
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
Makefile
Makefile.in
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
omp_printf
pth_barrier
pth_barrier_race
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cleanup_handler
pth_cond_race
pth_create_chain
pth_create_glibc_2_0
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_mutex_reinit
pth_process_shared_mutex
pth_spinlock
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
rwlock_type_checking
sem_as_mutex
sem_open
sigalrm
tc01_simple_race
tc02_simple_tls
tc03_re_excl
tc04_free_lock
tc05_simple_race
tc06_two_races
tc07_hbl1
tc08_hbl2
tc09_bad_unlock
tc10_rec_lock
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
thread_name
trylock
tsan_unittest
unit_bitmap
unit_vc
vg_regtest.tmp*
Modified: trunk/drd/tests/Makefile.am
===================================================================
--- trunk/drd/tests/Makefile.am 2009-07-27 14:48:06 UTC (rev 10637)
+++ trunk/drd/tests/Makefile.am 2009-07-27 16:03:51 UTC (rev 10638)
@@ -144,6 +144,8 @@
rwlock_race.vgtest \
rwlock_test.stderr.exp \
rwlock_test.vgtest \
+ rwlock_type_checking.stderr.exp \
+ rwlock_type_checking.vgtest \
sem_as_mutex.stderr.exp \
sem_as_mutex.vgtest \
sem_as_mutex2.stderr.exp \
@@ -254,6 +256,7 @@
recursive_mutex \
rwlock_race \
rwlock_test \
+ rwlock_type_checking \
sem_as_mutex \
sem_open \
sigalrm \
Added: trunk/drd/tests/rwlock_type_checking.c
===================================================================
--- trunk/drd/tests/rwlock_type_checking.c (rev 0)
+++ trunk/drd/tests/rwlock_type_checking.c 2009-07-27 16:03:51 UTC (rev 10638)
@@ -0,0 +1,35 @@
+/**
+ * @file rwlock_type_checking.c
+ *
+ * @brief Test whether DRD reports attempts to use a user-defined rwlock as
+ * a POSIX rwlock and vice versa.
+ */
+
+
+#define _GNU_SOURCE 1
+
+#include <pthread.h>
+#include <stdio.h>
+#include "../../config.h"
+#include "../../drd/drd.h"
+
+
+int main(int argc, char** argv)
+{
+ pthread_rwlock_t posix_rwlock;
+ int user_defined_rwlock;
+
+ ANNOTATE_RWLOCK_CREATE(&user_defined_rwlock);
+ pthread_rwlock_init(&posix_rwlock, 0);
+
+ pthread_rwlock_rdlock((pthread_rwlock_t*)&user_defined_rwlock);
+
+ ANNOTATE_READERLOCK_ACQUIRED(&posix_rwlock);
+
+ pthread_rwlock_destroy(&posix_rwlock);
+ ANNOTATE_RWLOCK_DESTROY(&user_defined_rwlock);
+
+ fprintf(stderr, "Finished.\n");
+
+ return 0;
+}
Added: trunk/drd/tests/rwlock_type_checking.stderr.exp
===================================================================
--- trunk/drd/tests/rwlock_type_checking.stderr.exp (rev 0)
+++ trunk/drd/tests/rwlock_type_checking.stderr.exp 2009-07-27 16:03:51 UTC (rev 10638)
@@ -0,0 +1,31 @@
+
+Attempt to use a user-defined rwlock as a POSIX rwlock: rwlock 0x.........
+ at 0x........: pthread_rwlock_rdlock* (drd_pthread_intercepts.c:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+rwlock 0x........ was first observed at:
+ at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+
+Attempt to use a POSIX rwlock as a user-defined rwlock: rwlock 0x.........
+ at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+
+Destroying locked rwlock: rwlock 0x.........
+ at 0x........: pthread_rwlock_destroy* (drd_pthread_intercepts.c:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+rwlock 0x........ was first observed at:
+ at 0x........: pthread_rwlock_init* (drd_pthread_intercepts.c:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+
+Destroying locked rwlock: rwlock 0x.........
+ at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+rwlock 0x........ was first observed at:
+ at 0x........: vgDrdCl_annotate_rwlock (drd.h:?)
+ by 0x........: main (rwlock_type_checking.c:?)
+Finished.
+
+ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Added: trunk/drd/tests/rwlock_type_checking.vgtest
===================================================================
--- trunk/drd/tests/rwlock_type_checking.vgtest (rev 0)
+++ trunk/drd/tests/rwlock_type_checking.vgtest 2009-07-27 16:03:51 UTC (rev 10638)
@@ -0,0 +1,4 @@
+prereq: test -e rwlock_type_checking && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no
+prog: rwlock_type_checking
+stderr_filter: filter_stderr
|