mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
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. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10638
This commit is contained in:
parent
4a6e44dd44
commit
df0bcd77a8
@ -124,6 +124,7 @@ struct rwlock_info
|
||||
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;
|
||||
|
||||
@ -194,9 +194,40 @@ static void DRD_(rwlock_combine_other_vc)(struct rwlock_info* const p,
|
||||
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 @@ void DRD_(rwlock_initialize)(struct rwlock_info* const p, const Addr rwlock)
|
||||
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 void rwlock_cleanup(struct rwlock_info* p)
|
||||
|
||||
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 @@ DRD_(rwlock_get_or_allocate)(const Addr rwlock)
|
||||
}
|
||||
|
||||
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 @@ struct rwlock_info* DRD_(rwlock_pre_init)(const Addr rwlock,
|
||||
return p;
|
||||
}
|
||||
|
||||
p = DRD_(rwlock_get_or_allocate)(rwlock);
|
||||
p = DRD_(rwlock_get_or_allocate)(rwlock, rwlock_type);
|
||||
|
||||
return p;
|
||||
}
|
||||
@ -350,7 +385,7 @@ void DRD_(rwlock_pre_rdlock)(const Addr rwlock, const RwLockT rwlock_type)
|
||||
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 @@ void DRD_(rwlock_pre_wrlock)(const Addr rwlock, const RwLockT rwlock_type)
|
||||
}
|
||||
|
||||
if (p == 0)
|
||||
p = DRD_(rwlock_get_or_allocate)(rwlock);
|
||||
p = DRD_(rwlock_get_or_allocate)(rwlock, rwlock_type);
|
||||
|
||||
tl_assert(p);
|
||||
|
||||
|
||||
@ -144,6 +144,8 @@ EXTRA_DIST = \
|
||||
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 @@ check_PROGRAMS = \
|
||||
recursive_mutex \
|
||||
rwlock_race \
|
||||
rwlock_test \
|
||||
rwlock_type_checking \
|
||||
sem_as_mutex \
|
||||
sem_open \
|
||||
sigalrm \
|
||||
|
||||
35
drd/tests/rwlock_type_checking.c
Normal file
35
drd/tests/rwlock_type_checking.c
Normal file
@ -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;
|
||||
}
|
||||
31
drd/tests/rwlock_type_checking.stderr.exp
Normal file
31
drd/tests/rwlock_type_checking.stderr.exp
Normal file
@ -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)
|
||||
4
drd/tests/rwlock_type_checking.vgtest
Normal file
4
drd/tests/rwlock_type_checking.vgtest
Normal file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user