From: Bart Van Assche Date: Sun, 2 Mar 2008 17:43:18 +0000 (+0000) Subject: Added support for POSIX reader-writer locks. Modified exp-drd/tests/filter-stderr... X-Git-Tag: svn/VALGRIND_3_4_0~987 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1c0e43670ff10c2cbf0af398c83a0c750fc73114;p=thirdparty%2Fvalgrind.git Added support for POSIX reader-writer locks. Modified exp-drd/tests/filter-stderr such that i386 and AMD64 now generate the same output. Removed *.stderr.exp2 files. Added section that explains differences between LinuxThreads and NPTL to exp-drd/docs/README.txt. Made error message about LinuxThreads more clear. Made error messages more uniform. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7531 --- diff --git a/exp-drd/Makefile.am b/exp-drd/Makefile.am index 49c6b346e8..9f336ab043 100644 --- a/exp-drd/Makefile.am +++ b/exp-drd/Makefile.am @@ -81,6 +81,7 @@ DRD_SOURCES_COMMON = \ drd_main.c \ drd_malloc_wrappers.c \ drd_mutex.c \ + drd_rwlock.c \ drd_segment.c \ drd_semaphore.c \ drd_suppression.c \ @@ -96,6 +97,7 @@ noinst_HEADERS = \ drd_error.h \ drd_malloc_wrappers.h \ drd_mutex.h \ + drd_rwlock.h \ drd_segment.h \ drd_semaphore.h \ drd_suppression.h \ diff --git a/exp-drd/docs/README.txt b/exp-drd/docs/README.txt index 1f4cbd0f2c..1e69058fb6 100644 --- a/exp-drd/docs/README.txt +++ b/exp-drd/docs/README.txt @@ -30,10 +30,10 @@ source reading by a human. It takes a huge effort however to detect all possible data races or deadlocks via source reading. This is why tools for detecting data races and deadlocks at runtime are essential. -The de facto standard library for multithreading on Unix systems is -the POSIX threads library, also known as pthreads. The exp-drd tool -has been developed for multithreaded software that uses the POSIX -threads library. +The de facto standard library for multithreading with the C and C++ +programming languages on Unix systems is the POSIX threads library, +also known as pthreads. The exp-drd tool has been developed for +multithreaded software that uses the POSIX threads library. Data Races @@ -202,7 +202,22 @@ An approach that has proven to work for interthread communication between real-time threads is the use of preallocated fixed size message queueus, and to lock any data needed by any real-time thread in memory (mlock()). Avoid mutexes with priority inheritance -- see -also [Yodaiken 2004] for more information. +also [Yodaiken 2004] for more information. Lock-free data structures +like circular buffers are well suited for real-time software. + + +Linux and POSIX Threads +----------------------- + +There exist two implementations of the POSIX threads API for +Linux. These implementations are called LinuxThreads and +NPTL. LinuxThreads was historically the first POSIX threads +implementation for Linux. LinuxThreads was compliant to most but not +all POSIX threads specifications. That is why a new threading library +for Linux was developed, called the NPTL (Native POSIX Threads +Library). Most Linux distributions switched from LinuxThreads to NPTL +around 2004. DRD only supports the NPTL. See also [Shukla 2006] for +more information. How to use DRD @@ -373,6 +388,12 @@ References http://iacoma.cs.uiuc.edu/iacoma-papers/asid06.pdf http://portal.acm.org/citation.cfm?id=1181309.1181315 +[Shukla 2006] + Vikram Shukla + NPTL -- A rundown of the key differences for developers who need to port + July 31, 2006. + http://www-128.ibm.com/developerworks/linux/library/l-threading.html?ca=dgr-lnxw07LinuxThreadsAndNPTL + [Müehlenfeld 2007] Arndt Müehlenfeld, Franz Wotawa. Fault Detection in Multi-threaded C++ Server Applications. diff --git a/exp-drd/drd_clientobj.h b/exp-drd/drd_clientobj.h index 831d5434cf..ffd13ca738 100644 --- a/exp-drd/drd_clientobj.h +++ b/exp-drd/drd_clientobj.h @@ -45,6 +45,7 @@ typedef enum { ClientCondvar = 2, ClientSemaphore = 3, ClientBarrier = 4, + ClientRwlock = 5, } ObjType; struct any @@ -96,12 +97,21 @@ struct barrier_info Addr a2; ObjType type; void (*cleanup)(union drd_clientobj*); - Word count; // Participant count in a barrier wait. - Word pre_iteration; // pthread_barrier_wait() call count modulo two. - Word post_iteration; // pthread_barrier_wait() call count modulo two. - Word pre_waiters_left; // number of waiters left for a complete barrier. - Word post_waiters_left; // number of waiters left for a complete barrier. - OSet* oset; // Thread-specific barrier information. + Word count; // Participant count in a barrier wait. + Word pre_iteration; // pthread_barrier_wait() call count modulo two. + Word post_iteration; // pthread_barrier_wait() call count modulo two. + Word pre_waiters_left; // number of waiters left for a complete barrier. + Word post_waiters_left; // number of waiters left for a complete barrier. + OSet* oset; // Thread-specific barrier information. +}; + +struct rwlock_info +{ + Addr a1; + Addr a2; + ObjType type; + void (*cleanup)(union drd_clientobj*); + OSet* thread_info; }; typedef union drd_clientobj @@ -111,6 +121,7 @@ typedef union drd_clientobj struct cond_info cond; struct semaphore_info semaphore; struct barrier_info barrier; + struct rwlock_info rwlock; } DrdClientobj; diff --git a/exp-drd/drd_clientreq.c b/exp-drd/drd_clientreq.c index 6ca6f7e0b7..20d1aa3db5 100644 --- a/exp-drd/drd_clientreq.c +++ b/exp-drd/drd_clientreq.c @@ -30,6 +30,7 @@ #include "drd_suppression.h" // drd_start_suppression() #include "drd_thread.h" #include "drd_track.h" +#include "drd_rwlock.h" #include "priv_drd_clientreq.h" #include "pub_tool_basics.h" // Bool #include "pub_tool_libcassert.h" @@ -214,24 +215,31 @@ static Bool drd_handle_client_request(ThreadId tid, UWord* arg, UWord* ret) break; case VG_USERREQ__PRE_RWLOCK_INIT: + rwlock_pre_init(arg[1], arg[2]); break; case VG_USERREQ__POST_RWLOCK_DESTROY: + rwlock_post_destroy(arg[1]); break; case VG_USERREQ__PRE_RWLOCK_RDLOCK: + rwlock_pre_rdlock(arg[1], arg[2]); break; case VG_USERREQ__POST_RWLOCK_RDLOCK: + rwlock_post_rdlock(arg[1], arg[2]); break; case VG_USERREQ__PRE_RWLOCK_WRLOCK: + rwlock_pre_wrlock(arg[1], arg[2]); break; case VG_USERREQ__POST_RWLOCK_WRLOCK: + rwlock_post_wrlock(arg[1], arg[2]); break; - case VG_USERREQ__POST_RWLOCK_UNLOCK: + case VG_USERREQ__PRE_RWLOCK_UNLOCK: + rwlock_pre_unlock(arg[1]); break; default: diff --git a/exp-drd/drd_clientreq.h b/exp-drd/drd_clientreq.h index 5d4e7aacf9..12bc5e35f0 100644 --- a/exp-drd/drd_clientreq.h +++ b/exp-drd/drd_clientreq.h @@ -128,7 +128,7 @@ enum { VG_USERREQ__POST_RWLOCK_WRLOCK, /* args: Addr rwlock, Bool took_lock */ /* To notify the drd tool of a pthread_rwlock_unlock call. */ - VG_USERREQ__POST_RWLOCK_UNLOCK, + VG_USERREQ__PRE_RWLOCK_UNLOCK, /* args: Addr rwlock, Bool unlocked */ }; diff --git a/exp-drd/drd_error.c b/exp-drd/drd_error.c index 60f31d7beb..9d701647f7 100644 --- a/exp-drd/drd_error.c +++ b/exp-drd/drd_error.c @@ -261,7 +261,7 @@ static void drd_tool_error_pp(Error* const e) MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); VG_(message)(Vg_UserMsg, - "%s: address 0x%lx, recursion count %d, owner %d.", + "%s: mutex 0x%lx, recursion count %d, owner %d.", VG_(get_error_string)(e), p->mutex, p->recursion_count, @@ -272,7 +272,7 @@ static void drd_tool_error_pp(Error* const e) case CondErr: { CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, - "cond 0x%lx: %s", + "%s: cond 0x%lx", cdei->cond, VG_(get_error_string)(e)); VG_(pp_ExeContext)(VG_(get_error_where)(e)); @@ -300,7 +300,7 @@ static void drd_tool_error_pp(Error* const e) SemaphoreErrInfo* sei =(SemaphoreErrInfo*)(VG_(get_error_extra)(e)); tl_assert(sei); VG_(message)(Vg_UserMsg, - "%s 0x%lx", + "%s: semaphore 0x%lx", VG_(get_error_string)(e), sei->semaphore); VG_(pp_ExeContext)(VG_(get_error_where)(e)); @@ -316,6 +316,16 @@ static void drd_tool_error_pp(Error* const e) VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } + case RwlockErr: { + RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e)); + tl_assert(p); + VG_(message)(Vg_UserMsg, + "%s: rwlock 0x%lx.", + VG_(get_error_string)(e), + p->rwlock); + VG_(pp_ExeContext)(VG_(get_error_where)(e)); + break; + } case GenericErr: { //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e)); @@ -349,6 +359,8 @@ static UInt drd_tool_error_update_extra(Error* e) return sizeof(SemaphoreErrInfo); case BarrierErr: return sizeof(BarrierErrInfo); + case RwlockErr: + return sizeof(RwlockErrInfo); case GenericErr: return sizeof(GenericErrInfo); default: @@ -387,9 +399,15 @@ static Char* drd_tool_error_name(Error* e) { switch (VG_(get_error_kind)(e)) { - case DataRaceErr: return "ConflictingAccess"; - case MutexErr: return "MutexErr"; - case CondRaceErr: return "CondRaceErr"; + case DataRaceErr: return "DataRaceErr"; + case MutexErr: return "MutexErr"; + case CondErr: return "CondErr"; + case CondRaceErr: return "CondRaceErr"; + case CondDestrErr: return "CondDestrErr"; + case SemaphoreErr: return "SemaphoreErr"; + case BarrierErr: return "BarrierErr"; + case RwlockErr: return "RwlockErr"; + case GenericErr: return "GenericErr"; default: tl_assert(0); } diff --git a/exp-drd/drd_error.h b/exp-drd/drd_error.h index 9dfdd61f16..660736619f 100644 --- a/exp-drd/drd_error.h +++ b/exp-drd/drd_error.h @@ -44,7 +44,8 @@ typedef enum { CondDestrErr = 5, SemaphoreErr = 6, BarrierErr = 7, - GenericErr = 8, + RwlockErr = 8, + GenericErr = 9, } DrdErrorKind; /* The classification of a faulting address. */ @@ -112,6 +113,10 @@ typedef struct { Addr barrier; } BarrierErrInfo; +typedef struct { + Addr rwlock; +} RwlockErrInfo; + typedef struct { } GenericErrInfo; diff --git a/exp-drd/drd_intercepts.c b/exp-drd/drd_intercepts.c index 9c67416a08..706ec1efc2 100644 --- a/exp-drd/drd_intercepts.c +++ b/exp-drd/drd_intercepts.c @@ -143,11 +143,23 @@ static void* vg_thread_wrapper(void* arg) if (getpid() != vg_main_thread_pid) { - fprintf(stderr, - "Detected the linuxthreads threading library.\n" - "Sorry, but DRD does not support linuxthreads.\n" - "Please try to run DRD on a system with NPTL instead.\n" - "Giving up.\n"); + if (getenv("LD_ASSUME_KERNEL")) + { + fprintf(stderr, +"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n" +"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n" +"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n" + ); + } + else + { + fprintf(stderr, +"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n" +"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n" +"after having upgraded to a newer version of your Linux distribution.\n" +"Giving up.\n" + ); + } abort(); } @@ -940,7 +952,7 @@ PTH_FUNC(int, OrigFn fn; VALGRIND_GET_ORIG_FN(fn); CALL_FN_W_W(ret, fn, rwlock); - VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK, + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK, rwlock, ret == 0, 0, 0, 0); return ret; } diff --git a/exp-drd/drd_mutex.c b/exp-drd/drd_mutex.c index 7793145b98..1178a3a110 100644 --- a/exp-drd/drd_mutex.c +++ b/exp-drd/drd_mutex.c @@ -159,7 +159,7 @@ mutex_init(const Addr mutex, const SizeT size, const MutexT mutex_type) VG_(maybe_record_error)(VG_(get_running_tid)(), GenericErr, VG_(get_IP)(VG_(get_running_tid)()), - "Invalid mutex", + "Not a mutex", &GEI); return 0; } @@ -231,7 +231,7 @@ void mutex_pre_lock(const Addr mutex, const SizeT size, MutexT mutex_type) VG_(maybe_record_error)(VG_(get_running_tid)(), GenericErr, VG_(get_IP)(VG_(get_running_tid)()), - "Invalid mutex", + "Not a mutex", &GEI); return; } @@ -261,7 +261,7 @@ void mutex_pre_lock(const Addr mutex, const SizeT size, MutexT mutex_type) * Note: this function must be called after pthread_mutex_lock() has been * called, or a race condition is triggered ! */ -int mutex_post_lock(const Addr mutex, const Bool took_lock) +void mutex_post_lock(const Addr mutex, const Bool took_lock) { const DrdThreadId drd_tid = thread_get_running_tid(); struct mutex_info* p; @@ -280,13 +280,8 @@ int mutex_post_lock(const Addr mutex, const Bool took_lock) p ? p->owner : VG_INVALID_THREADID); } - if (p == 0) - { - return 0; - } - - if (! took_lock) - return p->recursion_count; + if (! p || ! took_lock) + return; if (p->recursion_count == 0) { @@ -312,8 +307,6 @@ int mutex_post_lock(const Addr mutex, const Bool took_lock) thread_combine_vc2(drd_tid, mutex_get_last_vc(mutex)); thread_new_segment(drd_tid); } - - return p->recursion_count; } /** @@ -325,37 +318,26 @@ int mutex_post_lock(const Addr mutex, const Bool took_lock) * @param tid ThreadId of the thread calling pthread_mutex_unlock(). * @param vc Pointer to the current vector clock of thread tid. */ -int mutex_unlock(const Addr mutex, const MutexT mutex_type) +void mutex_unlock(const Addr mutex, const MutexT mutex_type) { const DrdThreadId drd_tid = thread_get_running_tid(); const ThreadId vg_tid = VG_(get_running_tid)(); const VectorClock* const vc = thread_get_vc(drd_tid); struct mutex_info* const p = mutex_get(mutex); - if (s_trace_mutex && p != 0) + if (s_trace_mutex) { VG_(message)(Vg_UserMsg, "[%d/%d] mutex_unlock %s 0x%lx rc %d", vg_tid, drd_tid, - mutex_get_typename(p), + p ? mutex_get_typename(p) : "?", mutex, - p->recursion_count, - p->owner); - } - - if (mutex_type == mutex_type_invalid_mutex) - { - GenericErrInfo GEI; - VG_(maybe_record_error)(VG_(get_running_tid)(), - GenericErr, - VG_(get_IP)(VG_(get_running_tid)()), - "Invalid mutex", - &GEI); - return 0; + p ? p->recursion_count : 0, + p ? p->owner : 0); } - if (p == 0) + if (p == 0 || mutex_type == mutex_type_invalid_mutex) { GenericErrInfo GEI; VG_(maybe_record_error)(vg_tid, @@ -363,7 +345,7 @@ int mutex_unlock(const Addr mutex, const MutexT mutex_type) VG_(get_IP)(vg_tid), "Not a mutex", &GEI); - return 0; + return; } if (p->owner == DRD_INVALID_THREADID) @@ -374,7 +356,7 @@ int mutex_unlock(const Addr mutex, const MutexT mutex_type) VG_(get_IP)(vg_tid), "Mutex not locked", &MEI); - return 0; + return; } tl_assert(p); @@ -386,27 +368,19 @@ int mutex_unlock(const Addr mutex, const MutexT mutex_type) tl_assert(p->mutex_type == mutex_type); tl_assert(p->owner != DRD_INVALID_THREADID); - if (p->owner != drd_tid) + if (p->owner != drd_tid || p->recursion_count <= 0) { MutexErrInfo MEI = { p->a1, p->recursion_count, p->owner }; VG_(maybe_record_error)(vg_tid, MutexErr, VG_(get_IP)(vg_tid), - "Mutex not unlocked by owner thread", + "Mutex not locked by calling thread", &MEI); + return; } + tl_assert(p->recursion_count > 0); p->recursion_count--; - if (p->recursion_count < 0) - { - MutexErrInfo MEI - = { p->a1, p->recursion_count, p->owner }; - VG_(maybe_record_error)(vg_tid, - MutexErr, - VG_(get_IP)(vg_tid), - "Attempt to unlock a mutex that is not locked", - &MEI); - p->recursion_count = 0; - } + tl_assert(p->recursion_count >= 0); if (p->recursion_count == 0) { @@ -417,7 +391,6 @@ int mutex_unlock(const Addr mutex, const MutexT mutex_type) thread_new_segment(drd_tid); } - return p->recursion_count; } const char* mutex_get_typename(struct mutex_info* const p) diff --git a/exp-drd/drd_mutex.h b/exp-drd/drd_mutex.h index d4db34065e..27cc5d0aad 100644 --- a/exp-drd/drd_mutex.h +++ b/exp-drd/drd_mutex.h @@ -26,8 +26,8 @@ // Mutex state information: owner thread and recursion count. -#ifndef __MUTEX_H -#define __MUTEX_H +#ifndef __DRD_MUTEX_H +#define __DRD_MUTEX_H #include "drd_clientreq.h" // MutexT @@ -46,8 +46,8 @@ void mutex_post_destroy(const Addr mutex); struct mutex_info* mutex_get(const Addr mutex); void mutex_pre_lock(const Addr mutex, const SizeT size, const MutexT mutex_type); -int mutex_post_lock(const Addr mutex, const Bool took_lock); -int mutex_unlock(const Addr mutex, const MutexT mutex_type); +void mutex_post_lock(const Addr mutex, const Bool took_lock); +void mutex_unlock(const Addr mutex, const MutexT mutex_type); const char* mutex_get_typename(struct mutex_info* const p); const char* mutex_type_name(const MutexT mt); Bool mutex_is_locked_by(const Addr mutex, const DrdThreadId tid); @@ -57,4 +57,4 @@ void mutex_thread_delete(const DrdThreadId tid); ULong get_mutex_lock_count(void); -#endif /* __MUTEX_H */ +#endif /* __DRD_MUTEX_H */ diff --git a/exp-drd/drd_rwlock.c b/exp-drd/drd_rwlock.c new file mode 100644 index 0000000000..ac0560ba78 --- /dev/null +++ b/exp-drd/drd_rwlock.c @@ -0,0 +1,519 @@ +/* + This file is part of drd, a data race detector. + + Copyright (C) 2006-2008 Bart Van Assche + bart.vanassche@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + + +#include "drd_clientobj.h" +#include "drd_error.h" +#include "drd_rwlock.h" +#include "priv_drd_clientreq.h" +#include "pub_tool_errormgr.h" // VG_(maybe_record_error)() +#include "pub_tool_libcassert.h" // tl_assert() +#include "pub_tool_libcprint.h" // VG_(message)() +#include "pub_tool_machine.h" // VG_(get_IP)() +#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)() +#include "pub_tool_threadstate.h" // VG_(get_running_tid)() + + +// Type definitions. + +struct rwlock_thread_info +{ + UWord tid; // DrdThreadId. + UInt reader_nesting_count; + UInt writer_nesting_count; + VectorClock vc; // Vector clock associated with last unlock by this thread. +}; + + +// Local functions. + +static void rwlock_cleanup(struct rwlock_info* p); + + +// Local variables. + +static Bool s_trace_rwlock; + + +// Function definitions. + +void rwlock_set_trace(const Bool trace_rwlock) +{ + tl_assert(!! trace_rwlock == trace_rwlock); + s_trace_rwlock = trace_rwlock; +} + +static Bool rwlock_is_rdlocked(struct rwlock_info* p) +{ + struct rwlock_thread_info* q; + + VG_(OSetGen_ResetIter)(p->thread_info); + for ( ; (q = VG_(OSetGen_Next)(p->thread_info)); q++) + { + return q->reader_nesting_count > 0; + } + return False; +} + +static Bool rwlock_is_wrlocked(struct rwlock_info* p) +{ + struct rwlock_thread_info* q; + + VG_(OSetGen_ResetIter)(p->thread_info); + for ( ; (q = VG_(OSetGen_Next)(p->thread_info)); q++) + { + return q->writer_nesting_count > 0; + } + return False; +} + +static Bool rwlock_is_locked(struct rwlock_info* p) +{ + return rwlock_is_rdlocked(p) || rwlock_is_wrlocked(p); +} + +static Bool rwlock_is_rdlocked_by(struct rwlock_info* p, const DrdThreadId tid) +{ + const UWord uword_tid = tid; + struct rwlock_thread_info* q; + + q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid); + return q && q->reader_nesting_count > 0; +} + +static Bool rwlock_is_wrlocked_by(struct rwlock_info* p, const DrdThreadId tid) +{ + const UWord uword_tid = tid; + struct rwlock_thread_info* q; + + q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid); + return q && q->writer_nesting_count > 0; +} + +static Bool rwlock_is_locked_by(struct rwlock_info* p, const DrdThreadId tid) +{ + return rwlock_is_rdlocked_by(p, tid) || rwlock_is_wrlocked_by(p, tid); +} + +static +struct rwlock_thread_info* lookup_or_insert_node(OSet* oset, const UWord tid) +{ + struct rwlock_thread_info* q; + + q = VG_(OSetGen_Lookup)(oset, &tid); + if (q == 0) + { + q = VG_(OSetGen_AllocNode)(oset, sizeof(*q)); + q->tid = tid; + q->reader_nesting_count = 0; + q->writer_nesting_count = 0; + vc_init(&q->vc, 0, 0); + VG_(OSetGen_Insert)(oset, q); + } + tl_assert(q); + return q; +} + +static void rwlock_combine_other_vc(struct rwlock_info* const p, + const DrdThreadId tid) +{ + struct rwlock_thread_info* q; + + VG_(OSetGen_ResetIter)(p->thread_info); + for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; ) + { + if (q->tid != tid) + { + thread_combine_vc2(tid, &q->vc); + } + } +} + +static +void rwlock_initialize(struct rwlock_info* const p, + const Addr rwlock, + const SizeT size) +{ + tl_assert(rwlock != 0); + tl_assert(size > 0); + tl_assert(p->a1 == rwlock); + tl_assert(p->a2 == rwlock + size); + tl_assert(p->type == ClientRwlock); + + p->cleanup = (void(*)(DrdClientobj*))&rwlock_cleanup; + p->thread_info = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free)); +} + +/** Deallocate the memory that was allocated by rwlock_initialize(). */ +static void rwlock_cleanup(struct rwlock_info* p) +{ + struct rwlock_thread_info* q; + + tl_assert(p); + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] rwlock_destroy 0x%lx", + VG_(get_running_tid)(), + thread_get_running_tid(), + p->a1); + } + + if (rwlock_is_locked(p)) + { + RwlockErrInfo REI = { p->a1 }; + VG_(maybe_record_error)(VG_(get_running_tid)(), + RwlockErr, + VG_(get_IP)(VG_(get_running_tid)()), + "Destroying locked rwlock", + &REI); + } + + VG_(OSetGen_ResetIter)(p->thread_info); + for ( ; (q = VG_(OSetGen_Next)(p->thread_info)); q++) + { + vc_cleanup(&q->vc); + } + VG_(OSetGen_Destroy)(p->thread_info); +} + +static +struct rwlock_info* +rwlock_get_or_allocate(const Addr rwlock, const SizeT size) +{ + struct rwlock_info* p; + + tl_assert(offsetof(DrdClientobj, rwlock) == 0); + p = &clientobj_get(rwlock, ClientRwlock)->rwlock; + if (p) + { + tl_assert(p->a2 - p->a1 == size); + return p; + } + + if (clientobj_present(rwlock, rwlock + size)) + { + GenericErrInfo GEI; + VG_(maybe_record_error)(VG_(get_running_tid)(), + GenericErr, + VG_(get_IP)(VG_(get_running_tid)()), + "Not a reader-writer lock", + &GEI); + return 0; + } + + p = &clientobj_add(rwlock, rwlock + size, ClientRwlock)->rwlock; + rwlock_initialize(p, rwlock, size); + return p; +} + +static struct rwlock_info* rwlock_get(const Addr rwlock) +{ + tl_assert(offsetof(DrdClientobj, rwlock) == 0); + return &clientobj_get(rwlock, ClientRwlock)->rwlock; +} + +/** Called before pthread_rwlock_init(). */ +struct rwlock_info* +rwlock_pre_init(const Addr rwlock, const SizeT size) +{ + struct rwlock_info* p; + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] rwlock_init %s 0x%lx", + VG_(get_running_tid)(), + thread_get_running_tid(), + rwlock); + } + + p = rwlock_get(rwlock); + + if (p) + { + const ThreadId vg_tid = VG_(get_running_tid)(); + RwlockErrInfo REI + = { p->a1 }; + VG_(maybe_record_error)(vg_tid, + RwlockErr, + VG_(get_IP)(vg_tid), + "Reader-writer lock reinitialization", + &REI); + return p; + } + + p = rwlock_get_or_allocate(rwlock, size); + + return p; +} + +/** Called after pthread_rwlock_destroy(). */ +void rwlock_post_destroy(const Addr rwlock) +{ + struct rwlock_info* p; + + p = rwlock_get(rwlock); + if (p == 0) + { + GenericErrInfo GEI; + VG_(maybe_record_error)(VG_(get_running_tid)(), + GenericErr, + VG_(get_IP)(VG_(get_running_tid)()), + "Not a reader-writer lock", + &GEI); + return; + } + + clientobj_remove(rwlock, ClientRwlock); +} + +/** Called before pthread_rwlock_rdlock() is invoked. If a data structure for + * the client-side object was not yet created, do this now. Also check whether + * an attempt is made to lock recursively a synchronization object that must + * not be locked recursively. + */ +void rwlock_pre_rdlock(const Addr rwlock, const SizeT size) +{ + struct rwlock_info* p; + + p = rwlock_get_or_allocate(rwlock, size); + + tl_assert(p); + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] pre_rwlock_rdlock 0x%lx", + VG_(get_running_tid)(), + thread_get_running_tid(), + rwlock); + } + + if (rwlock_is_wrlocked_by(p, thread_get_running_tid())) + { + VG_(message)(Vg_UserMsg, + "reader-writer lock 0x%lx is already locked for" + " writing by calling thread", + p->a1); + } +} + +/** + * Update rwlock_info state when locking the pthread_rwlock_t mutex. + * Note: this function must be called after pthread_rwlock_rdlock() has been + * called, or a race condition is triggered ! + */ +void rwlock_post_rdlock(const Addr rwlock, const Bool took_lock) +{ + const DrdThreadId drd_tid = thread_get_running_tid(); + struct rwlock_info* p; + struct rwlock_thread_info* q; + + p = rwlock_get(rwlock); + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] post_rwlock_rdlock 0x%lx", + VG_(get_running_tid)(), + drd_tid, + rwlock); + } + + if (! p || ! took_lock) + return; + + tl_assert(! rwlock_is_wrlocked(p)); + + q = lookup_or_insert_node(p->thread_info, drd_tid); + if (++q->reader_nesting_count == 1) + { + rwlock_combine_other_vc(p, drd_tid); + thread_new_segment(drd_tid); + } +} + +/** Called before pthread_rwlock_wrlock() is invoked. If a data structure for + * the client-side object was not yet created, do this now. Also check whether + * an attempt is made to lock recursively a synchronization object that must + * not be locked recursively. + */ +void rwlock_pre_wrlock(const Addr rwlock, const SizeT size) +{ + struct rwlock_info* p; + + p = rwlock_get(rwlock); + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] pre_rwlock_wrlock 0x%lx", + VG_(get_running_tid)(), + thread_get_running_tid(), + rwlock); + } + + if (p == 0) + { + p = rwlock_get_or_allocate(rwlock, size); + } + + tl_assert(p); + + if (rwlock_is_wrlocked_by(p, thread_get_running_tid())) + { + RwlockErrInfo REI = { p->a1 }; + VG_(maybe_record_error)(VG_(get_running_tid)(), + RwlockErr, + VG_(get_IP)(VG_(get_running_tid)()), + "Recursive writer locking not allowed", + &REI); + } +} + +/** + * Update rwlock_info state when locking the pthread_rwlock_t rwlock. + * Note: this function must be called after pthread_rwlock_wrlock() has been + * called, or a race condition is triggered ! + */ +void rwlock_post_wrlock(const Addr rwlock, const Bool took_lock) +{ + const DrdThreadId drd_tid = thread_get_running_tid(); + struct rwlock_info* p; + struct rwlock_thread_info* q; + + p = rwlock_get(rwlock); + + if (s_trace_rwlock) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] post_rwlock_wrlock 0x%lx", + VG_(get_running_tid)(), + drd_tid, + rwlock); + } + + if (! p || ! took_lock) + return; + + q = lookup_or_insert_node(p->thread_info, thread_get_running_tid()); + tl_assert(q->writer_nesting_count == 0); + q->writer_nesting_count++; + tl_assert(q->writer_nesting_count == 1); + rwlock_combine_other_vc(p, drd_tid); + thread_new_segment(drd_tid); +} + +/** + * Update rwlock_info state when unlocking the pthread_rwlock_t rwlock. + * Note: this function must be called before pthread_rwlock_unlock() is called, + * or a race condition is triggered ! + * @return New value of the rwlock recursion count. + * @param rwlock Pointer to pthread_rwlock_t data structure in the client space. + * @param tid ThreadId of the thread calling pthread_rwlock_unlock(). + * @param vc Pointer to the current vector clock of thread tid. + */ +void rwlock_pre_unlock(const Addr rwlock) +{ + const DrdThreadId drd_tid = thread_get_running_tid(); + const ThreadId vg_tid = VG_(get_running_tid)(); + const VectorClock* const vc = thread_get_vc(drd_tid); + struct rwlock_info* const p = rwlock_get(rwlock); + struct rwlock_thread_info* q; + + if (s_trace_rwlock && p != 0) + { + VG_(message)(Vg_UserMsg, + "[%d/%d] rwlock_unlock 0x%lx", + vg_tid, + drd_tid, + rwlock); + } + + if (p == 0 || ! rwlock_is_locked_by(p, drd_tid)) + { + RwlockErrInfo REI = { p->a1 }; + VG_(maybe_record_error)(vg_tid, + RwlockErr, + VG_(get_IP)(vg_tid), + "Reader-writer lock not locked by calling thread", + &REI); + return; + } + tl_assert(p); + q = lookup_or_insert_node(p->thread_info, drd_tid); + tl_assert(q); + if (q->reader_nesting_count > 0) + q->reader_nesting_count--; + else if (q->writer_nesting_count > 0) + q->writer_nesting_count--; + else + tl_assert(False); + + if (q->reader_nesting_count == 0 && q->writer_nesting_count == 0) + { + /* This pthread_rwlock_unlock() call really unlocks the rwlock. Save the */ + /* current vector clock of the thread such that it is available when */ + /* this rwlock is locked again. */ + vc_assign(&q->vc, vc); + + thread_new_segment(drd_tid); + } +} + +/** + * Call this function when thread tid stops to exist, such that the + * "last owner" field can be cleared if it still refers to that thread. + */ +void rwlock_thread_delete(const DrdThreadId tid) +{ + struct rwlock_info* p; + + clientobj_resetiter(); + for ( ; (p = &clientobj_next(ClientRwlock)->rwlock) != 0; ) + { + struct rwlock_thread_info* q; + if (rwlock_is_locked_by(p, tid)) + { + RwlockErrInfo REI = { p->a1 }; + VG_(maybe_record_error)(VG_(get_running_tid)(), + RwlockErr, + VG_(get_IP)(VG_(get_running_tid)()), + "Reader-writer lock still locked at thread exit", + &REI); + q = lookup_or_insert_node(p->thread_info, tid); + q->reader_nesting_count = 0; + q->writer_nesting_count = 0; + } + } +} + + +/* + * Local variables: + * c-basic-offset: 2 + * End: + */ diff --git a/exp-drd/drd_rwlock.h b/exp-drd/drd_rwlock.h new file mode 100644 index 0000000000..b73db9330b --- /dev/null +++ b/exp-drd/drd_rwlock.h @@ -0,0 +1,53 @@ +/* + This file is part of drd, a data race detector. + + Copyright (C) 2006-2008 Bart Van Assche + bart.vanassche@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + + +// Reader-writer lock state information. + + +#ifndef __DRD_RWLOCK_H +#define __DRD_RWLOCK_H + + +#include "drd_clientobj.h" // struct rwlock_info +#include "drd_thread.h" // DrdThreadId +#include "drd_vc.h" +#include "pub_tool_basics.h" // Addr, SizeT + + +struct rwlock_info; + + +void rwlock_set_trace(const Bool trace_rwlock); +struct rwlock_info* rwlock_pre_init(const Addr rwlock, const SizeT size); +void rwlock_post_destroy(const Addr rwlock); +void rwlock_pre_rdlock(const Addr rwlock, const SizeT size); +void rwlock_post_rdlock(const Addr rwlock, const Bool took_lock); +void rwlock_pre_wrlock(const Addr rwlock, const SizeT size); +void rwlock_post_wrlock(const Addr rwlock, const Bool took_lock); +void rwlock_pre_unlock(const Addr rwlock); +void rwlock_thread_delete(const DrdThreadId tid); + + +#endif /* __DRD_RWLOCK_H */ diff --git a/exp-drd/tests/Makefile.am b/exp-drd/tests/Makefile.am index 30657edd2c..903ac7f6e1 100644 --- a/exp-drd/tests/Makefile.am +++ b/exp-drd/tests/Makefile.am @@ -16,7 +16,6 @@ noinst_SCRIPTS = \ EXTRA_DIST = $(noinst_SCRIPTS) \ fp_race.vgtest \ fp_race.stdout.exp fp_race.stderr.exp \ - fp_race.stderr.exp2 \ fp_race2.vgtest \ fp_race2.stdout.exp fp_race2.stderr.exp \ hg01_all_ok.vgtest \ @@ -25,10 +24,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ hg02_deadlock.stderr.exp \ hg03_inherit.vgtest \ hg03_inherit.stderr.exp \ - hg03_inherit.stderr.exp2 \ hg04_race.vgtest \ hg04_race.stderr.exp \ - hg04_race.stderr.exp2 \ hg05_race2.vgtest \ hg05_race2.stderr.exp \ hg06_readshared.vgtest \ @@ -51,13 +48,10 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ pth_detached2.vgtest \ pth_detached2.stdout.exp pth_detached2.stderr.exp \ recursive_mutex.vgtest recursive_mutex.stderr.exp \ - sem_as_mutex.vgtest \ - sem_as_mutex.stderr.exp sem_as_mutex.stderr.exp2 \ - sem_as_mutex2.vgtest \ - sem_as_mutex2.stderr.exp \ + sem_as_mutex.vgtest sem_as_mutex.stderr.exp \ + sem_as_mutex2.vgtest sem_as_mutex2.stderr.exp \ tc01_simple_race.vgtest \ tc01_simple_race.stderr.exp \ - tc01_simple_race.stderr.exp2 \ tc02_simple_tls.vgtest \ tc02_simple_tls.stderr.exp \ tc03_re_excl.vgtest \ @@ -74,7 +68,6 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ tc10_rec_lock.stderr.exp \ tc11_XCHG.vgtest \ tc11_XCHG.stderr.exp tc11_XCHG.stdout.exp \ - tc11_XCHG.stderr.exp2 \ tc12_rwl_trivial.vgtest \ tc12_rwl_trivial.stderr.exp \ tc13_laog1.vgtest \ @@ -83,17 +76,14 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ tc15_laog_lockdel.stderr.exp \ tc16_byterace.vgtest \ tc16_byterace.stderr.exp \ - tc16_byterace.stderr.exp2 \ tc17_sembar.vgtest \ tc17_sembar.stderr.exp \ tc18_semabuse.vgtest \ tc18_semabuse.stderr.exp \ tc19_shadowmem.vgtest \ tc19_shadowmem.stderr.exp \ - tc20_verifywrap.vgtest \ - tc20_verifywrap.stderr.exp tc20_verifywrap.stderr.exp2 \ - tc20_verifywrap2.vgtest \ - tc20_verifywrap2.stderr.exp tc20_verifywrap2.stderr.exp2\ + tc20_verifywrap.vgtest tc20_verifywrap.stderr.exp \ + tc20_verifywrap2.vgtest tc20_verifywrap2.stderr.exp \ tc21_pthonce.vgtest \ tc21_pthonce.stderr.exp tc21_pthonce.stdout.exp \ tc22_exit_w_lock.vgtest \ diff --git a/exp-drd/tests/filter_stderr b/exp-drd/tests/filter_stderr index c592cf302f..63c49aa2e2 100755 --- a/exp-drd/tests/filter_stderr +++ b/exp-drd/tests/filter_stderr @@ -11,6 +11,7 @@ $dir/../../tests/filter_stderr_basic | sed \ -e "/^exp-drd, a data race detector\.$/d" \ -e "s/^Allocation context: stack of thread \([0-9]*\), offset -[0-9]*$/Allocation context: stack of thread \1, offset .../" \ +-e "s/^Allocation context: .*$/Allocation context: unknown/" \ -e "/^NOTE: This is an Experimental-Class Valgrind Tool.$/d" \ -e "/^Copyright (C) 2006-200., and GNU GPL'd, by Bart Van Assche.$/d" \ -e "s/\(pthread_create.c:[0-9]*\)/in libpthread-?.?.so/" \ diff --git a/exp-drd/tests/fp_race.stderr.exp b/exp-drd/tests/fp_race.stderr.exp index 1a44269152..c9afafd7b1 100644 --- a/exp-drd/tests/fp_race.stderr.exp +++ b/exp-drd/tests/fp_race.stderr.exp @@ -1,7 +1,7 @@ Conflicting load by main at 0x........ size 8 at 0x........: main (fp_race.c:?) -Allocation context: s_d3 (offset 0, size 8) in fp_race, NONE:BSS +Allocation context: unknown Other segment start (thread_func) (thread finished, call stack no longer available) Other segment end (thread_func) @@ -9,7 +9,7 @@ Other segment end (thread_func) Conflicting store by main at 0x........ size 8 at 0x........: main (fp_race.c:?) -Allocation context: s_d3 (offset 0, size 8) in fp_race, NONE:BSS +Allocation context: unknown Other segment start (thread_func) (thread finished, call stack no longer available) Other segment end (thread_func) diff --git a/exp-drd/tests/fp_race.stderr.exp2 b/exp-drd/tests/fp_race.stderr.exp2 deleted file mode 100644 index c9afafd7b1..0000000000 --- a/exp-drd/tests/fp_race.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by main at 0x........ size 8 - at 0x........: main (fp_race.c:?) -Allocation context: unknown -Other segment start (thread_func) - (thread finished, call stack no longer available) -Other segment end (thread_func) - (thread finished, call stack no longer available) - -Conflicting store by main at 0x........ size 8 - at 0x........: main (fp_race.c:?) -Allocation context: unknown -Other segment start (thread_func) - (thread finished, call stack no longer available) -Other segment end (thread_func) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/hg03_inherit.stderr.exp2 b/exp-drd/tests/hg03_inherit.stderr.exp2 deleted file mode 100644 index 274c6a726e..0000000000 --- a/exp-drd/tests/hg03_inherit.stderr.exp2 +++ /dev/null @@ -1,31 +0,0 @@ - -Thread 3: -Conflicting store by thread 3 at 0x........ size 4 - at 0x........: t2 (hg03_inherit.c:28) - by 0x........: vg_thread_wrapper (drd_intercepts.c:?) - by 0x........: start_thread (in libpthread-?.?.so) - by 0x........: clone (in /...libc...) -Allocation context: unknown -Other segment start (thread 1) - at 0x........: pthread_join (drd_intercepts.c:?) - by 0x........: main (hg03_inherit.c:49) -Other segment end (thread 1) - at 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_intercepts.c:?) - by 0x........: main (hg03_inherit.c:63) - -Conflicting store by thread 3 at 0x........ size 4 - at 0x........: t2 (hg03_inherit.c:29) - by 0x........: vg_thread_wrapper (drd_intercepts.c:?) - by 0x........: start_thread (in libpthread-?.?.so) - by 0x........: clone (in /...libc...) -Allocation context: unknown -Other segment start (thread 1) - at 0x........: pthread_join (drd_intercepts.c:?) - by 0x........: main (hg03_inherit.c:49) -Other segment end (thread 1) - at 0x........: pthread_join (in libpthread-?.?.so) - by 0x........: pthread_join (drd_intercepts.c:?) - by 0x........: main (hg03_inherit.c:63) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/hg04_race.stderr.exp2 b/exp-drd/tests/hg04_race.stderr.exp2 deleted file mode 100644 index c713aff4b9..0000000000 --- a/exp-drd/tests/hg04_race.stderr.exp2 +++ /dev/null @@ -1,25 +0,0 @@ - -Thread 2: -Conflicting load by thread 2 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vg_thread_wrapper (drd_intercepts.c:?) - by 0x........: start_thread (in libpthread-?.?.so) - by 0x........: clone (in /...libc...) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 2 at 0x........ size 4 - at 0x........: th (hg04_race.c:10) - by 0x........: vg_thread_wrapper (drd_intercepts.c:?) - by 0x........: start_thread (in libpthread-?.?.so) - by 0x........: clone (in /...libc...) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/hg05_race2.stderr.exp b/exp-drd/tests/hg05_race2.stderr.exp index c4999e2dda..da70ded1e5 100644 --- a/exp-drd/tests/hg05_race2.stderr.exp +++ b/exp-drd/tests/hg05_race2.stderr.exp @@ -5,7 +5,7 @@ Conflicting load by thread 2 at 0x........ size 4 by 0x........: vg_thread_wrapper (drd_intercepts.c:?) by 0x........: start_thread (in libpthread-?.?.so) by 0x........: clone (in /...libc...) -Allocation context: stack of thread 1, offset ... +Allocation context: unknown Other segment start (thread 2) (thread finished, call stack no longer available) Other segment end (thread 2) @@ -16,7 +16,7 @@ Conflicting store by thread 2 at 0x........ size 4 by 0x........: vg_thread_wrapper (drd_intercepts.c:?) by 0x........: start_thread (in libpthread-?.?.so) by 0x........: clone (in /...libc...) -Allocation context: stack of thread 1, offset ... +Allocation context: unknown Other segment start (thread 2) (thread finished, call stack no longer available) Other segment end (thread 2) diff --git a/exp-drd/tests/recursive_mutex.stderr.exp b/exp-drd/tests/recursive_mutex.stderr.exp index 4384a2bea0..8369d7be35 100644 --- a/exp-drd/tests/recursive_mutex.stderr.exp +++ b/exp-drd/tests/recursive_mutex.stderr.exp @@ -1,15 +1,15 @@ -Recursive locking not allowed: address 0x........, recursion count 1, owner 1. +Recursive locking not allowed: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_lock (drd_intercepts.c:?) by 0x........: lock_twice (recursive_mutex.c:?) by 0x........: main (recursive_mutex.c:?) -Attempt to unlock a mutex that is not locked: address 0x........, recursion count -1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 0, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: lock_twice (recursive_mutex.c:?) by 0x........: main (recursive_mutex.c:?) -Recursive locking not allowed: address 0x........, recursion count 1, owner 1. +Recursive locking not allowed: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_lock (drd_intercepts.c:?) by 0x........: lock_twice (recursive_mutex.c:?) by 0x........: main (recursive_mutex.c:?) diff --git a/exp-drd/tests/sem_as_mutex.stderr.exp b/exp-drd/tests/sem_as_mutex.stderr.exp index c2a2f3265e..8c396090a9 100644 --- a/exp-drd/tests/sem_as_mutex.stderr.exp +++ b/exp-drd/tests/sem_as_mutex.stderr.exp @@ -1,7 +1,7 @@ Conflicting load by main at 0x........ size 8 at 0x........: main (sem_as_mutex.c:?) -Allocation context: s_d3 (offset 0, size 8) in sem_as_mutex, NONE:BSS +Allocation context: unknown Other segment start (thread_func) (thread finished, call stack no longer available) Other segment end (thread_func) @@ -9,7 +9,7 @@ Other segment end (thread_func) Conflicting store by main at 0x........ size 8 at 0x........: main (sem_as_mutex.c:?) -Allocation context: s_d3 (offset 0, size 8) in sem_as_mutex, NONE:BSS +Allocation context: unknown Other segment start (thread_func) (thread finished, call stack no longer available) Other segment end (thread_func) diff --git a/exp-drd/tests/sem_as_mutex.stderr.exp2 b/exp-drd/tests/sem_as_mutex.stderr.exp2 deleted file mode 100644 index 8c396090a9..0000000000 --- a/exp-drd/tests/sem_as_mutex.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by main at 0x........ size 8 - at 0x........: main (sem_as_mutex.c:?) -Allocation context: unknown -Other segment start (thread_func) - (thread finished, call stack no longer available) -Other segment end (thread_func) - (thread finished, call stack no longer available) - -Conflicting store by main at 0x........ size 8 - at 0x........: main (sem_as_mutex.c:?) -Allocation context: unknown -Other segment start (thread_func) - (thread finished, call stack no longer available) -Other segment end (thread_func) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc01_simple_race.stderr.exp2 b/exp-drd/tests/tc01_simple_race.stderr.exp2 deleted file mode 100644 index 8a2b91a99b..0000000000 --- a/exp-drd/tests/tc01_simple_race.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: main (tc01_simple_race.c:28) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: main (tc01_simple_race.c:28) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc04_free_lock.stderr.exp b/exp-drd/tests/tc04_free_lock.stderr.exp index 953a3f226e..fbb85cd91f 100644 --- a/exp-drd/tests/tc04_free_lock.stderr.exp +++ b/exp-drd/tests/tc04_free_lock.stderr.exp @@ -1,17 +1,17 @@ -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: free (vg_replace_malloc.c:...) by 0x........: main (tc04_free_lock.c:24) -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: bar (tc04_free_lock.c:40) by 0x........: main (tc04_free_lock.c:26) -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: foo (tc04_free_lock.c:49) by 0x........: main (tc04_free_lock.c:27) -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: bar (tc04_free_lock.c:40) by 0x........: main (tc04_free_lock.c:28) diff --git a/exp-drd/tests/tc04_free_lock.stderr.exp2 b/exp-drd/tests/tc04_free_lock.stderr.exp2 deleted file mode 100644 index 768b25e597..0000000000 --- a/exp-drd/tests/tc04_free_lock.stderr.exp2 +++ /dev/null @@ -1,14 +0,0 @@ - -Destroying locked mutex: address 0x........, recursion count 1, owner 1. - at 0x........: bar (tc04_free_lock.c:40) - by 0x........: (below main) (in /...libc...) - -Destroying locked mutex: address 0x........, recursion count 1, owner 1. - at 0x........: foo (tc04_free_lock.c:49) - by 0x........: (below main) (in /...libc...) - -Destroying locked mutex: address 0x........, recursion count 1, owner 1. - at 0x........: bar (tc04_free_lock.c:40) - by 0x........: (below main) (in /...libc...) - -ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc06_two_races.stderr.exp2 b/exp-drd/tests/tc06_two_races.stderr.exp2 deleted file mode 100644 index 4cbed89c1a..0000000000 --- a/exp-drd/tests/tc06_two_races.stderr.exp2 +++ /dev/null @@ -1 +0,0 @@ -ERROR SUMMARY: 4 errors from 4 contexts diff --git a/exp-drd/tests/tc07_hbl1.stderr.exp2 b/exp-drd/tests/tc07_hbl1.stderr.exp2 deleted file mode 100644 index 10f0ca1088..0000000000 --- a/exp-drd/tests/tc07_hbl1.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: main (tc07_hbl1.c:68) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: main (tc07_hbl1.c:68) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc09_bad_unlock.stderr.exp b/exp-drd/tests/tc09_bad_unlock.stderr.exp index c12b6bdfb9..052df38c19 100644 --- a/exp-drd/tests/tc09_bad_unlock.stderr.exp +++ b/exp-drd/tests/tc09_bad_unlock.stderr.exp @@ -1,11 +1,11 @@ -Attempt to unlock a mutex that is not locked: address 0x........, recursion count -1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 0, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: nearly_main (tc09_bad_unlock.c:27) by 0x........: main (tc09_bad_unlock.c:49) Thread 2: -Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: child_fn (tc09_bad_unlock.c:11) by 0x........: vg_thread_wrapper (drd_intercepts.c:?) @@ -13,18 +13,22 @@ Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner by 0x........: clone (in /...libc...) Thread 1: -Invalid mutex +Not a mutex at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: nearly_main (tc09_bad_unlock.c:41) by 0x........: main (tc09_bad_unlock.c:49) -Attempt to unlock a mutex that is not locked: address 0x........, recursion count -1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. + at 0x........: nearly_main (tc09_bad_unlock.c:45) + by 0x........: main (tc09_bad_unlock.c:49) + +Mutex not locked by calling thread: mutex 0x........, recursion count 0, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: nearly_main (tc09_bad_unlock.c:27) by 0x........: main (tc09_bad_unlock.c:50) Thread 2: -Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: child_fn (tc09_bad_unlock.c:11) by 0x........: vg_thread_wrapper (drd_intercepts.c:?) @@ -32,9 +36,13 @@ Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner by 0x........: clone (in /...libc...) Thread 1: -Invalid mutex +Not a mutex at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: nearly_main (tc09_bad_unlock.c:41) by 0x........: main (tc09_bad_unlock.c:50) -ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. + at 0x........: nearly_main (tc09_bad_unlock.c:45) + by 0x........: main (tc09_bad_unlock.c:50) + +ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc10_rec_lock.stderr.exp b/exp-drd/tests/tc10_rec_lock.stderr.exp index 705c9e6c60..43adfac0f8 100644 --- a/exp-drd/tests/tc10_rec_lock.stderr.exp +++ b/exp-drd/tests/tc10_rec_lock.stderr.exp @@ -6,7 +6,7 @@ before unlock #1 before unlock #2 before unlock #3 before unlock #4 -Attempt to unlock a mutex that is not locked: address 0x........, recursion count -1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 0, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: nearly_main (tc10_rec_lock.c:42) by 0x........: main (tc10_rec_lock.c:47) diff --git a/exp-drd/tests/tc11_XCHG.stderr.exp2 b/exp-drd/tests/tc11_XCHG.stderr.exp2 deleted file mode 100644 index f715e4b002..0000000000 --- a/exp-drd/tests/tc11_XCHG.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by thread 1 at 0x........ size 4 - at 0x........: main (tc11_XCHG.c:78) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 4 - at 0x........: main (tc11_XCHG.c:78) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc12_rwl_trivial.stderr.exp b/exp-drd/tests/tc12_rwl_trivial.stderr.exp index d18786f806..b4e22cf1c5 100644 --- a/exp-drd/tests/tc12_rwl_trivial.stderr.exp +++ b/exp-drd/tests/tc12_rwl_trivial.stderr.exp @@ -1,3 +1,6 @@ +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc12_rwl_trivial.c:29) -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc16_byterace.stderr.exp2 b/exp-drd/tests/tc16_byterace.stderr.exp2 deleted file mode 100644 index 84db3ce31f..0000000000 --- a/exp-drd/tests/tc16_byterace.stderr.exp2 +++ /dev/null @@ -1,18 +0,0 @@ - -Conflicting load by thread 1 at 0x........ size 1 - at 0x........: main (tc16_byterace.c:34) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -Conflicting store by thread 1 at 0x........ size 1 - at 0x........: main (tc16_byterace.c:34) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - -ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc18_semabuse.stderr.exp b/exp-drd/tests/tc18_semabuse.stderr.exp index dd534669df..764a3a5088 100644 --- a/exp-drd/tests/tc18_semabuse.stderr.exp +++ b/exp-drd/tests/tc18_semabuse.stderr.exp @@ -1,5 +1,5 @@ -Invalid semaphore 0x........ +Invalid semaphore: semaphore 0x........ at 0x........: sem_wait* (drd_intercepts.c:?) by 0x........: main (tc18_semabuse.c:34) diff --git a/exp-drd/tests/tc20_verifywrap.stderr.exp b/exp-drd/tests/tc20_verifywrap.stderr.exp index 731008b1bb..40b607d8f7 100644 --- a/exp-drd/tests/tc20_verifywrap.stderr.exp +++ b/exp-drd/tests/tc20_verifywrap.stderr.exp @@ -7,7 +7,7 @@ Conflicting store by thread 1 at 0x........ size 2 at 0x........: main (tc20_verifywrap.c:78) -Allocation context: unprotected (offset 0, size 2) in tc20_verifywrap, NONE:BSS +Allocation context: unknown Other segment start (thread 2) (thread finished, call stack no longer available) Other segment end (thread 2) @@ -16,34 +16,34 @@ Other segment end (thread 2) ---------------- pthread_mutex_lock et al ---------------- -Invalid mutex +Not a mutex at 0x........: pthread_mutex_init (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:92) -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_destroy (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:102) -Invalid mutex +Not a mutex at 0x........: pthread_mutex_lock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:108) -Invalid mutex +Not a mutex at 0x........: pthread_mutex_trylock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:116) -Invalid mutex +Not a mutex at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:121) -Invalid mutex +Not a mutex at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:125) ---------------- pthread_cond_wait et al ---------------- -Mutex not locked: address 0x........, recursion count 0, owner 0. +Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_wait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:147) @@ -53,28 +53,44 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal FIXME: can't figure out how to verify wrap of pthread_broadcast_signal -Mutex not locked: address 0x........, recursion count 0, owner 0. +Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:165) ---------------- pthread_rwlock_* ---------------- + +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:179) (1) no error on next line (2) no error on next line (3) ERROR on next line + +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:196) + +Reader-writer lock reinitialization: rwlock 0x......... + at 0x........: pthread_rwlock_init* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:199) (4) no error on next line (5) no error on next line (6) no error on next line (7) no error on next line (8) ERROR on next line +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:212) + ---------------- sem_* ---------------- FIXME: can't figure out how to verify wrap of sem_destroy -Invalid semaphore 0x........ +Invalid semaphore: semaphore 0x........ at 0x........: sem_wait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:242) @@ -84,4 +100,7 @@ FIXME: can't figure out how to verify wrap of sem_post ------------ dealloc of mem holding locks ------------ -ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0) +Destroying locked rwlock: rwlock 0x......... + at 0x........: main (tc20_verifywrap.c:262) + +ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc20_verifywrap.stderr.exp2 b/exp-drd/tests/tc20_verifywrap.stderr.exp2 deleted file mode 100644 index e56f57d312..0000000000 --- a/exp-drd/tests/tc20_verifywrap.stderr.exp2 +++ /dev/null @@ -1,87 +0,0 @@ - - - ------- This is output for >= glibc 2.4 ------ - ----------------- pthread_create/join ---------------- - -Conflicting store by thread 1 at 0x........ size 2 - at 0x........: main (tc20_verifywrap.c:78) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - ----------------- pthread_mutex_lock et al ---------------- - - -Invalid mutex - at 0x........: pthread_mutex_init (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:92) - -Destroying locked mutex: address 0x........, recursion count 1, owner 1. - at 0x........: pthread_mutex_destroy (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:102) - -Invalid mutex - at 0x........: pthread_mutex_lock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:108) - -Invalid mutex - at 0x........: pthread_mutex_trylock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:116) - -Invalid mutex - at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:121) - -Invalid mutex - at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:125) - ----------------- pthread_cond_wait et al ---------------- - - -Mutex not locked: address 0x........, recursion count 0, owner 0. - at 0x........: pthread_cond_wait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:147) - -FIXME: can't figure out how to verify wrap of pthread_cond_signal - - -FIXME: can't figure out how to verify wrap of pthread_broadcast_signal - - -Mutex not locked: address 0x........, recursion count 0, owner 0. - at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:165) - ----------------- pthread_rwlock_* ---------------- - -(1) no error on next line -(2) no error on next line -(3) ERROR on next line -(4) no error on next line -(5) no error on next line -(6) no error on next line -(7) no error on next line -(8) ERROR on next line - ----------------- sem_* ---------------- - - -FIXME: can't figure out how to verify wrap of sem_destroy - - -Invalid semaphore 0x........ - at 0x........: sem_wait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:242) - -FIXME: can't figure out how to verify wrap of sem_post - - ------------- dealloc of mem holding locks ------------ - - -ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc20_verifywrap2.stderr.exp b/exp-drd/tests/tc20_verifywrap2.stderr.exp index 28534ed041..4ac981c16f 100644 --- a/exp-drd/tests/tc20_verifywrap2.stderr.exp +++ b/exp-drd/tests/tc20_verifywrap2.stderr.exp @@ -7,7 +7,7 @@ Conflicting store by thread 1 at 0x........ size 2 at 0x........: main (tc20_verifywrap.c:78) -Allocation context: unprotected (offset 0, size 2) in tc20_verifywrap, NONE:BSS +Allocation context: unknown Other segment start (thread 2) (thread finished, call stack no longer available) Other segment end (thread 2) @@ -17,7 +17,7 @@ Other segment end (thread 2) [1/1] mutex_init invalid mutex 0x........ -Invalid mutex +Not a mutex at 0x........: pthread_mutex_init (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:92) [1/1] mutex_init mutex 0x........ @@ -25,29 +25,30 @@ Invalid mutex [1/1] post_mutex_lock mutex 0x........ rc 0 owner 0 [1/1] mutex_destroy mutex 0x........ -Destroying locked mutex: address 0x........, recursion count 1, owner 1. +Destroying locked mutex: mutex 0x........, recursion count 1, owner 1. at 0x........: pthread_mutex_destroy (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:102) [1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 -Invalid mutex +Not a mutex at 0x........: pthread_mutex_lock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:108) [1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 [1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 -Invalid mutex +Not a mutex at 0x........: pthread_mutex_trylock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:116) [1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 [1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 -Invalid mutex +Not a mutex at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:121) [1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 +[1/1] mutex_unlock ? 0x........ rc 0 -Invalid mutex +Not a mutex at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:125) @@ -57,7 +58,7 @@ Invalid mutex [1/1] cond_init 0x........ [1/1] mutex_unlock error checking mutex 0x........ rc 0 -Mutex not locked: address 0x........, recursion count 0, owner 0. +Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_wait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:147) [1/1] cond_pre_wait 0x........ @@ -73,7 +74,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal [1/1] mutex_unlock error checking mutex 0x........ rc 0 -Mutex not locked: address 0x........, recursion count 0, owner 0. +Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:165) [1/1] cond_pre_wait 0x........ @@ -82,15 +83,31 @@ Mutex not locked: address 0x........, recursion count 0, owner 0. ---------------- pthread_rwlock_* ---------------- + +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:179) (1) no error on next line (2) no error on next line (3) ERROR on next line + +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:196) + +Reader-writer lock reinitialization: rwlock 0x......... + at 0x........: pthread_rwlock_init* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:199) (4) no error on next line (5) no error on next line (6) no error on next line (7) no error on next line (8) ERROR on next line +Reader-writer lock not locked by calling thread: rwlock 0x......... + at 0x........: pthread_rwlock_unlock* (drd_intercepts.c:?) + by 0x........: main (tc20_verifywrap.c:212) + ---------------- sem_* ---------------- [1/1] semaphore_init 0x........ @@ -100,7 +117,7 @@ FIXME: can't figure out how to verify wrap of sem_destroy [1/1] semaphore_pre_wait 0x........ [1/1] semaphore_post_wait 0x........ -Invalid semaphore 0x........ +Invalid semaphore: semaphore 0x........ at 0x........: sem_wait* (drd_intercepts.c:?) by 0x........: main (tc20_verifywrap.c:242) [1/1] semaphore_post 0x........ @@ -111,6 +128,9 @@ FIXME: can't figure out how to verify wrap of sem_post ------------ dealloc of mem holding locks ------------ + +Destroying locked rwlock: rwlock 0x......... + at 0x........: main (tc20_verifywrap.c:262) [1/1] mutex_destroy error checking mutex 0x........ [1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 [1/1] mutex_init recursive mutex 0x........ @@ -162,4 +182,4 @@ FIXME: can't figure out how to verify wrap of sem_post [1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 [1/1] mutex_unlock recursive mutex 0x........ rc 1 -ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0) +ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc20_verifywrap2.stderr.exp2 b/exp-drd/tests/tc20_verifywrap2.stderr.exp2 deleted file mode 100644 index 3f958cbf7b..0000000000 --- a/exp-drd/tests/tc20_verifywrap2.stderr.exp2 +++ /dev/null @@ -1,165 +0,0 @@ - - - ------- This is output for >= glibc 2.4 ------ - ----------------- pthread_create/join ---------------- - -Conflicting store by thread 1 at 0x........ size 2 - at 0x........: main (tc20_verifywrap.c:78) -Allocation context: unknown -Other segment start (thread 2) - (thread finished, call stack no longer available) -Other segment end (thread 2) - (thread finished, call stack no longer available) - ----------------- pthread_mutex_lock et al ---------------- - -[1/1] mutex_init invalid mutex 0x........ - -Invalid mutex - at 0x........: pthread_mutex_init (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:92) -[1/1] mutex_init mutex 0x........ -[1/1] pre_mutex_lock mutex 0x........ rc 0 owner 0 -[1/1] post_mutex_lock mutex 0x........ rc 0 owner 0 -[1/1] mutex_destroy mutex 0x........ - -Destroying locked mutex: address 0x........, recursion count 1, owner 1. - at 0x........: pthread_mutex_destroy (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:102) -[1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 - -Invalid mutex - at 0x........: pthread_mutex_lock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:108) -[1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 -[1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 - -Invalid mutex - at 0x........: pthread_mutex_trylock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:116) -[1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 -[1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 - -Invalid mutex - at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:121) -[1/1] post_mutex_lock (?) 0x........ rc 0 owner 0 - -Invalid mutex - at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:125) - ----------------- pthread_cond_wait et al ---------------- - -[1/1] mutex_init error checking mutex 0x........ -[1/1] cond_init 0x........ -[1/1] mutex_unlock error checking mutex 0x........ rc 0 - -Mutex not locked: address 0x........, recursion count 0, owner 0. - at 0x........: pthread_cond_wait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:147) -[1/1] cond_pre_wait 0x........ -[1/1] cond_post_wait 0x........ -[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0 -[1/1] cond_signal 0x........ - -FIXME: can't figure out how to verify wrap of pthread_cond_signal - -[1/1] cond_broadcast 0x........ - -FIXME: can't figure out how to verify wrap of pthread_broadcast_signal - -[1/1] mutex_unlock error checking mutex 0x........ rc 0 - -Mutex not locked: address 0x........, recursion count 0, owner 0. - at 0x........: pthread_cond_timedwait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:165) -[1/1] cond_pre_wait 0x........ -[1/1] cond_post_wait 0x........ -[1/1] post_mutex_lock error checking mutex 0x........ rc 0 owner 0 - ----------------- pthread_rwlock_* ---------------- - -(1) no error on next line -(2) no error on next line -(3) ERROR on next line -(4) no error on next line -(5) no error on next line -(6) no error on next line -(7) no error on next line -(8) ERROR on next line - ----------------- sem_* ---------------- - -[1/1] semaphore_init 0x........ - -FIXME: can't figure out how to verify wrap of sem_destroy - -[1/1] semaphore_pre_wait 0x........ -[1/1] semaphore_post_wait 0x........ - -Invalid semaphore 0x........ - at 0x........: sem_wait* (drd_intercepts.c:?) - by 0x........: main (tc20_verifywrap.c:242) -[1/1] semaphore_post 0x........ - -FIXME: can't figure out how to verify wrap of sem_post - -[1/1] semaphore_destroy 0x........ - ------------- dealloc of mem holding locks ------------ - -[1/1] mutex_destroy error checking mutex 0x........ -[1/1] pre_mutex_lock (?) 0x........ rc 0 owner 0 -[1/1] mutex_init recursive mutex 0x........ -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 0 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 -[1/1] pre_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1 -[1/1] mutex_unlock recursive mutex 0x........ rc 1 - -ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0) diff --git a/exp-drd/tests/tc23_bogus_condwait.stderr.exp b/exp-drd/tests/tc23_bogus_condwait.stderr.exp index 0d4d8ca335..379122a194 100644 --- a/exp-drd/tests/tc23_bogus_condwait.stderr.exp +++ b/exp-drd/tests/tc23_bogus_condwait.stderr.exp @@ -12,7 +12,7 @@ Race condition: condition variable 0x........ has been signalled but the associa by 0x........: clone (in /...libc...) Thread 1: -Mutex not locked: address 0x........, recursion count 0, owner 0. +Mutex not locked: mutex 0x........, recursion count 0, owner 0. at 0x........: pthread_cond_wait* (drd_intercepts.c:?) by 0x........: main (tc23_bogus_condwait.c:72) @@ -38,7 +38,7 @@ Race condition: condition variable 0x........ has been signalled but the associa by 0x........: clone (in /...libc...) Thread 1: -Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner 2. +Mutex not locked by calling thread: mutex 0x........, recursion count 1, owner 2. at 0x........: pthread_cond_wait* (drd_intercepts.c:?) by 0x........: main (tc23_bogus_condwait.c:78) @@ -49,9 +49,10 @@ Race condition: condition variable 0x........ has been signalled but the associa by 0x........: vg_thread_wrapper (drd_intercepts.c:?) by 0x........: start_thread (in libpthread-?.?.so) by 0x........: clone (in /...libc...) +The impossible happened: mutex 0x........ is locked simultaneously by two threads (recursion count 1, owners 2 and 1) ! Thread 2: -Mutex not unlocked by owner thread: address 0x........, recursion count 1, owner 1. +Mutex not locked by calling thread: mutex 0x........, recursion count 2, owner 1. at 0x........: pthread_mutex_unlock (drd_intercepts.c:?) by 0x........: grab_the_lock (tc23_bogus_condwait.c:42) by 0x........: vg_thread_wrapper (drd_intercepts.c:?)