Added detection of more types of runtime errors. Cleaned up tracing output. Added test for tracing output (tc20_verifywrap2).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7511 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_barrier.c b/exp-drd/drd_barrier.c
index b4fca3d..30c801e 100644
--- a/exp-drd/drd_barrier.c
+++ b/exp-drd/drd_barrier.c
@@ -123,8 +123,13 @@
if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
{
- VG_(message)(Vg_UserMsg, "Destruction of barrier 0x%lx being waited upon",
- p->a1);
+ BarrierErrInfo bei = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ BarrierErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Destruction of barrier that is being waited"
+ " upon",
+ &bei);
}
VG_(OSetGen_ResetIter)(p->oset);
@@ -168,6 +173,14 @@
struct barrier_info*
barrier_init(const Addr barrier, const SizeT size, const Word count)
{
+ if (s_trace_barrier)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] barrier_init 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ barrier);
+ }
tl_assert(barrier_get(barrier) == 0);
return barrier_get_or_allocate(barrier, size, count);
}
@@ -175,6 +188,14 @@
/** Called after pthread_barrier_destroy(). */
void barrier_destroy(struct barrier_info* const p)
{
+ if (s_trace_barrier)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] barrier_destroy 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ p->a1);
+ }
tl_assert(p);
drd_clientobj_remove(p->a1, ClientBarrier);
}
@@ -191,9 +212,12 @@
if (s_trace_barrier)
{
- VG_(message)(Vg_DebugMsg,
- "[%d] barrier_pre_wait(%p) iteration %d",
- tid, barrier, p->pre_iteration);
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] barrier_pre_wait 0x%lx iteration %d",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ barrier,
+ p->pre_iteration);
}
q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
@@ -218,14 +242,19 @@
void barrier_post_wait(const DrdThreadId tid, const Addr barrier,
const Bool waited)
{
- struct barrier_info* const p = barrier_get(barrier);
+ struct barrier_info* p;
+ p = barrier_get(barrier);
tl_assert(p);
if (s_trace_barrier)
{
- VG_(message)(Vg_DebugMsg, "[%d] barrier_post_wait(%p) iteration %d",
- tid, barrier, p->post_iteration);
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] barrier_post_wait 0x%lx iteration %d",
+ VG_(get_running_tid)(),
+ tid,
+ barrier,
+ p->post_iteration);
}
if (waited)
@@ -241,23 +270,7 @@
{
if (r != q)
{
- if (s_trace_barrier)
- {
- VG_(message)(Vg_DebugMsg,
- "[%d] barrier_post_wait: combining vc of thread %d, "
- "iteration %d",
- tid, r->tid, p->post_iteration);
- vc_print(&thread_get_segment(tid)->vc);
- VG_(printf)(", ");
- vc_print(&r->vc[p->post_iteration]);
- VG_(printf)(" -> ");
- }
thread_combine_vc2(tid, &r->vc[p->post_iteration]);
- if (s_trace_barrier)
- {
- vc_print(&thread_get_segment(tid)->vc);
- VG_(printf)("\n");
- }
}
}
diff --git a/exp-drd/drd_clientreq.c b/exp-drd/drd_clientreq.c
index 8d4191c..1de6851 100644
--- a/exp-drd/drd_clientreq.c
+++ b/exp-drd/drd_clientreq.c
@@ -61,10 +61,11 @@
}
static void drd_post_cond_wait(const Addr cond, const Addr mutex,
- const SizeT size, const MutexT mutex_type)
+ const SizeT size, const MutexT mutex_type,
+ const Bool took_lock)
{
cond_post_wait(cond);
- mutex_post_lock(mutex, size, mutex_type);
+ mutex_post_lock(mutex, size, mutex_type, took_lock);
}
static void drd_pre_cond_signal(const Addr cond)
@@ -144,7 +145,8 @@
break;
case VG_USERREQ__POST_PTHREAD_MUTEX_LOCK:
- drd_post_mutex_lock(thread_get_running_tid(), arg[1], arg[2], arg[3]);
+ drd_post_mutex_lock(thread_get_running_tid(),
+ arg[1], arg[2], arg[3], arg[4]);
break;
case VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK:
@@ -170,7 +172,8 @@
case VG_USERREQ__POST_PTHREAD_COND_WAIT:
drd_post_cond_wait(arg[1]/*cond*/, arg[2]/*mutex*/,
- arg[3]/*mutex_size*/, arg[4]/*mutex_type*/);
+ arg[3]/*mutex_size*/, arg[4]/*mutex_type*/,
+ arg[5]/*took_lock*/);
break;
case VG_USERREQ__PRE_PTHREAD_COND_SIGNAL:
diff --git a/exp-drd/drd_clientreq.h b/exp-drd/drd_clientreq.h
index a41e8d6..68cf741 100644
--- a/exp-drd/drd_clientreq.h
+++ b/exp-drd/drd_clientreq.h
@@ -63,7 +63,7 @@
/* args: Addr, SizeT, MutexT */
/* to notify the drd tool of pthread_mutex_lock calls */
VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- /* args: Addr, SizeT, MutexT */
+ /* args: Addr, SizeT, MutexT, Bool */
/* to notify the drd tool of pthread_mutex_unlock calls */
VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
/* args: Addr */
@@ -76,11 +76,11 @@
/* args: Addr */
/* to notify the drd tool of a pthread_cond_destroy call. */
VG_USERREQ__PRE_PTHREAD_COND_DESTROY,
- /* args: Addr cond, SizeT cond_size, Addr mutex, SizeT mutex_size, MutexT mt */
+ /* args: Addr cond, SizeT cond_size, Addr mutex, SizeT mutex_size,MutexT mt*/
VG_USERREQ__PRE_PTHREAD_COND_WAIT,
/* args: Addr cond, SizeT cond_size, Addr mutex, MutexT mt */
VG_USERREQ__POST_PTHREAD_COND_WAIT,
- /* args: Addr cond, Addr mutex, SizeT mutex_size, MutexT mt */
+ /* args: Addr cond, Addr mutex, SizeT mutex_size, MutexT mt, Bool took_lock*/
VG_USERREQ__PRE_PTHREAD_COND_SIGNAL,
/* args: Addr cond */
VG_USERREQ__PRE_PTHREAD_COND_BROADCAST,
diff --git a/exp-drd/drd_cond.c b/exp-drd/drd_cond.c
index 3de2f3b..4e2dbd0 100644
--- a/exp-drd/drd_cond.c
+++ b/exp-drd/drd_cond.c
@@ -77,10 +77,16 @@
{
struct mutex_info* q;
q = &drd_clientobj_get(p->mutex, ClientMutex)->mutex;
- VG_(message)(Vg_UserMsg,
- "Error: destroying condition variable 0x%lx while thread %d"
- " is waiting on it.\n",
- p->a1, q ? q->owner : -1);
+ tl_assert(q);
+ {
+ CondDestrErrInfo cde = { p->a1, q->a1, q->owner };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ CondDestrErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Destroying condition variable that is being"
+ " waited upon",
+ &cde);
+ }
}
}
@@ -110,8 +116,11 @@
{
if (s_trace_cond)
{
- VG_(message)(Vg_UserMsg, "Initializing condition variable 0x%lx", cond);
- VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_init 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ cond);
}
tl_assert(cond_get(cond) == 0);
tl_assert(size > 0);
@@ -123,8 +132,11 @@
{
if (s_trace_cond)
{
- VG_(message)(Vg_UserMsg, "Destroying condition variable 0x%lx", p->a1);
- VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_destroy 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ p->a1);
}
// TO DO: print a proper error message if waiter_count != 0.
@@ -138,7 +150,18 @@
{
struct cond_info* p;
+ if (s_trace_cond)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_pre_wait 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ cond);
+ }
+
p = cond_get_or_allocate(cond, cond_size);
+ tl_assert(p);
+
if (p->waiter_count == 0)
{
p->mutex = mutex;
@@ -158,6 +181,15 @@
{
struct cond_info* p;
+ if (s_trace_cond)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_post_wait 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ cond);
+ }
+
p = cond_get(cond);
tl_assert(p);
tl_assert(p->waiter_count > 0);
@@ -169,12 +201,12 @@
return p->waiter_count;
}
-/** Called before pthread_cond_signal(). */
-void cond_pre_signal(Addr const cond)
+static void cond_signal(Addr const cond)
{
const ThreadId vg_tid = VG_(get_running_tid)();
const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
struct cond_info* const cond_p = cond_get(cond);
+
if (cond_p && cond_p->waiter_count > 0)
{
if (! mutex_is_locked_by(cond_p->mutex, drd_tid))
@@ -196,10 +228,34 @@
}
}
+/** Called before pthread_cond_signal(). */
+void cond_pre_signal(Addr const cond)
+{
+ if (s_trace_cond)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_signal 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ cond);
+ }
+
+ cond_signal(cond);
+}
+
/** Called before pthread_cond_broadcast(). */
void cond_pre_broadcast(Addr const cond)
{
- cond_pre_signal(cond);
+ if (s_trace_cond)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] cond_broadcast 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ cond);
+ }
+
+ cond_signal(cond);
}
/** Called after pthread_cond_destroy(). */
diff --git a/exp-drd/drd_error.c b/exp-drd/drd_error.c
index 5e63e7c..60f31d7 100644
--- a/exp-drd/drd_error.c
+++ b/exp-drd/drd_error.c
@@ -269,16 +269,6 @@
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
- case CondRaceErr: {
- CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
- VG_(message)(Vg_UserMsg,
- "Race condition: condition variable 0x%lx has been signalled"
- " but the associated mutex 0x%lx is not locked by the"
- " signalling thread",
- cei->cond, cei->mutex);
- VG_(pp_ExeContext)(VG_(get_error_where)(e));
- break;
- }
case CondErr: {
CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
VG_(message)(Vg_UserMsg,
@@ -288,6 +278,44 @@
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
+ case CondRaceErr: {
+ CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
+ VG_(message)(Vg_UserMsg,
+ "Race condition: condition variable 0x%lx has been"
+ " signalled but the associated mutex 0x%lx is not locked"
+ " by the signalling thread",
+ cei->cond, cei->mutex);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
+ case CondDestrErr: {
+ CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
+ VG_(message)(Vg_UserMsg,
+ "%s: cond 0x%lx, mutex 0x%lx locked by thread %d",
+ cdi->cond, cdi->mutex, cdi->tid);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
+ case SemaphoreErr: {
+ SemaphoreErrInfo* sei =(SemaphoreErrInfo*)(VG_(get_error_extra)(e));
+ tl_assert(sei);
+ VG_(message)(Vg_UserMsg,
+ "%s 0x%lx",
+ VG_(get_error_string)(e),
+ sei->semaphore);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
+ case BarrierErr: {
+ BarrierErrInfo* sei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
+ tl_assert(sei);
+ VG_(message)(Vg_UserMsg,
+ "%s: barrier 0x%lx",
+ VG_(get_error_string)(e),
+ sei->barrier);
+ 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));
@@ -311,10 +339,16 @@
return sizeof(DataRaceErrInfo);
case MutexErr:
return sizeof(MutexErrInfo);
- case CondRaceErr:
- return sizeof(CondRaceErrInfo);
case CondErr:
return sizeof(CondErrInfo);
+ case CondRaceErr:
+ return sizeof(CondRaceErrInfo);
+ case CondDestrErr:
+ return sizeof(CondDestrErrInfo);
+ case SemaphoreErr:
+ return sizeof(SemaphoreErrInfo);
+ case BarrierErr:
+ return sizeof(BarrierErrInfo);
case GenericErr:
return sizeof(GenericErrInfo);
default:
diff --git a/exp-drd/drd_error.h b/exp-drd/drd_error.h
index e9a54c4..9dfdd61 100644
--- a/exp-drd/drd_error.h
+++ b/exp-drd/drd_error.h
@@ -39,9 +39,12 @@
typedef enum {
DataRaceErr = 1,
MutexErr = 2,
- CondRaceErr = 3,
- CondErr = 4,
- GenericErr = 5,
+ CondErr = 3,
+ CondRaceErr = 4,
+ CondDestrErr = 5,
+ SemaphoreErr = 6,
+ BarrierErr = 7,
+ GenericErr = 8,
} DrdErrorKind;
/* The classification of a faulting address. */
@@ -88,12 +91,26 @@
typedef struct {
Addr cond;
+} CondErrInfo;
+
+typedef struct {
+ Addr cond;
Addr mutex;
} CondRaceErrInfo;
typedef struct {
- Addr cond;
-} CondErrInfo;
+ Addr cond;
+ Addr mutex;
+ DrdThreadId tid;
+} CondDestrErrInfo;
+
+typedef struct {
+ Addr semaphore;
+} SemaphoreErrInfo;
+
+typedef struct {
+ Addr barrier;
+} BarrierErrInfo;
typedef struct {
} GenericErrInfo;
diff --git a/exp-drd/drd_intercepts.c b/exp-drd/drd_intercepts.c
index 2a56978..6e14d63 100644
--- a/exp-drd/drd_intercepts.c
+++ b/exp-drd/drd_intercepts.c
@@ -343,9 +343,9 @@
write(1, "", 0);
#endif
CALL_FN_W_W(ret, fn, mutex);
- if (ret == 0)
- VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
+ VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ mutex, sizeof(*mutex), mutex_type(mutex),
+ ret == 0, 0);
return ret;
}
@@ -358,11 +358,9 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
CALL_FN_W_W(ret, fn, mutex);
- if (ret == 0)
- {
- VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
- }
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ mutex, sizeof(*mutex), mutex_type(mutex),
+ ret == 0, 0);
return ret;
}
@@ -376,11 +374,9 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
CALL_FN_W_WW(ret, fn, mutex, abs_timeout);
- if (ret == 0)
- {
- VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- mutex, sizeof(*mutex), mutex_type(mutex), 0, 0);
- }
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ mutex, sizeof(*mutex), mutex_type(mutex),
+ ret == 0, 0);
return ret;
}
@@ -438,10 +434,12 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
- cond, sizeof(*cond), mutex, mutex_type(mutex), 0);
+ cond, sizeof(*cond), mutex, mutex_type(mutex),
+ 0);
CALL_FN_W_WW(ret, fn, cond, mutex);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
- cond, mutex, sizeof(*mutex), mutex_type(mutex), 0);
+ cond, mutex, sizeof(*mutex), mutex_type(mutex),
+ ret == 0);
return ret;
}
@@ -456,10 +454,12 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
- cond, sizeof(*cond), mutex, mutex_type(mutex), 0);
+ cond, sizeof(*cond), mutex, mutex_type(mutex),
+ 0);
CALL_FN_W_WWW(ret, fn, cond, mutex, abstime);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
- cond, mutex, sizeof(*mutex), mutex_type(mutex), 0);
+ cond, mutex, sizeof(*mutex), mutex_type(mutex),
+ ret == 0);
return ret;
}
@@ -531,12 +531,9 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
CALL_FN_W_W(ret, fn, spinlock);
- if (ret == 0)
- {
- VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- spinlock, sizeof(*spinlock),
- mutex_type_spinlock, 0, 0);
- }
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ spinlock, sizeof(*spinlock),
+ mutex_type_spinlock, ret == 0, 0);
return ret;
}
@@ -549,12 +546,9 @@
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
CALL_FN_W_W(ret, fn, spinlock);
- if (ret == 0)
- {
- VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
- spinlock, sizeof(*spinlock),
- mutex_type_spinlock, 0, 0);
- }
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ spinlock, sizeof(*spinlock),
+ mutex_type_spinlock, ret == 0, 0);
return ret;
}
diff --git a/exp-drd/drd_main.c b/exp-drd/drd_main.c
index 5b8b436..af447f3 100644
--- a/exp-drd/drd_main.c
+++ b/exp-drd/drd_main.c
@@ -428,9 +428,10 @@
void drd_post_mutex_lock(const DrdThreadId drd_tid,
const Addr mutex,
const SizeT size,
- const MutexT mutex_type)
+ const MutexT mutex_type,
+ const Bool took_lock)
{
- mutex_post_lock(mutex, size, mutex_type);
+ mutex_post_lock(mutex, size, mutex_type, took_lock);
}
void drd_pre_mutex_unlock(const DrdThreadId drd_tid,
diff --git a/exp-drd/drd_mutex.c b/exp-drd/drd_mutex.c
index ac8ddfe..568bf4d 100644
--- a/exp-drd/drd_mutex.c
+++ b/exp-drd/drd_mutex.c
@@ -78,11 +78,10 @@
{
if (s_trace_mutex)
{
- const ThreadId vg_tid = VG_(get_running_tid)();
- const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
- VG_(message)(Vg_DebugMsg,
- "drd_pre_mutex_destroy tid = %d/%d, %s 0x%lx",
- vg_tid, drd_tid,
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] mutex_destroy %s 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
mutex_get_typename(p),
p->a1);
}
@@ -133,6 +132,12 @@
return p;
}
+struct mutex_info* mutex_get(const Addr mutex)
+{
+ tl_assert(offsetof(DrdClientobj, mutex) == 0);
+ return &drd_clientobj_get(mutex, ClientMutex)->mutex;
+}
+
struct mutex_info*
mutex_init(const Addr mutex, const SizeT size, const MutexT mutex_type)
{
@@ -140,11 +145,10 @@
if (s_trace_mutex)
{
- const ThreadId vg_tid = VG_(get_running_tid)();
- const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(vg_tid);
- VG_(message)(Vg_DebugMsg,
- "drd_post_mutex_init tid = %d/%d, %s 0x%lx",
- vg_tid, drd_tid,
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] mutex_init %s 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
mutex_type_name(mutex_type),
mutex);
}
@@ -185,12 +189,6 @@
}
}
-struct mutex_info* mutex_get(const Addr mutex)
-{
- tl_assert(offsetof(DrdClientobj, mutex) == 0);
- return &drd_clientobj_get(mutex, ClientMutex)->mutex;
-}
-
/** Called before pthread_mutex_lock() 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
@@ -227,17 +225,17 @@
* 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 SizeT size, MutexT mutex_type)
+int mutex_post_lock(const Addr mutex, const SizeT size, MutexT mutex_type,
+ const Bool took_lock)
{
- const DrdThreadId drd_tid = VgThreadIdToDrdThreadId(VG_(get_running_tid)());
+ const DrdThreadId drd_tid = thread_get_running_tid();
struct mutex_info* const p = mutex_get_or_allocate(mutex, size, mutex_type);
if (s_trace_mutex)
{
- const ThreadId tid = DrdThreadIdToVgThreadId(drd_tid);
- VG_(message)(Vg_DebugMsg,
- "drd_post_mutex_lock tid = %d/%d, %s 0x%lx rc %d owner %d",
- tid,
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] post_mutex_lock %s 0x%lx rc %d owner %d",
+ VG_(get_running_tid)(),
drd_tid,
mutex_get_typename(p),
mutex,
@@ -266,10 +264,8 @@
return 0;
}
-#if 0
- tl_assert(mutex_type == mutex_type_mutex
- || mutex_type == mutex_type_spinlock);
-#endif
+ if (! took_lock)
+ return p->recursion_count;
tl_assert(p->mutex_type == mutex_type);
tl_assert(p->a2 - p->a1 == size);
@@ -281,7 +277,7 @@
}
else if (p->owner != drd_tid)
{
- VG_(message)(Vg_DebugMsg,
+ VG_(message)(Vg_UserMsg,
"The impossible happened: mutex 0x%lx is locked"
" simultaneously by two threads (recursion count %d,"
" owners %d and %d) !",
@@ -320,9 +316,10 @@
if (s_trace_mutex && p != 0)
{
- VG_(message)(Vg_DebugMsg,
- "drd_pre_mutex_unlock tid = %d/%d, %s 0x%lx rc %d",
- vg_tid, drd_tid,
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] mutex_unlock %s 0x%lx rc %d",
+ vg_tid,
+ drd_tid,
mutex_get_typename(p),
mutex,
p->recursion_count,
@@ -364,7 +361,7 @@
tl_assert(p);
if (p->mutex_type != mutex_type)
{
- VG_(message)(Vg_DebugMsg, "??? mutex %p: type changed from %d into %d",
+ VG_(message)(Vg_UserMsg, "??? mutex %p: type changed from %d into %d",
p->a1, p->mutex_type, mutex_type);
}
tl_assert(p->mutex_type == mutex_type);
diff --git a/exp-drd/drd_mutex.h b/exp-drd/drd_mutex.h
index 5c5c7a0..5c12c2b 100644
--- a/exp-drd/drd_mutex.h
+++ b/exp-drd/drd_mutex.h
@@ -44,8 +44,10 @@
const MutexT mutex_type);
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 SizeT size, const MutexT mutex_type);
+void mutex_pre_lock(const Addr mutex, const SizeT size,
+ const MutexT mutex_type);
+int mutex_post_lock(const Addr mutex, const SizeT size,
+ const MutexT mutex_type, const Bool took_lock);
int 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);
diff --git a/exp-drd/drd_semaphore.c b/exp-drd/drd_semaphore.c
index 51a15ae..513dcd1 100644
--- a/exp-drd/drd_semaphore.c
+++ b/exp-drd/drd_semaphore.c
@@ -78,8 +78,13 @@
{
if (p->waiters > 0)
{
- VG_(message)(Vg_UserMsg, "Error: destroying semaphore while %d threads are"
- "still waiting on the semaphore.\n", p->waiters);
+ SemaphoreErrInfo sei = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ SemaphoreErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Destruction of semaphore that is being waited"
+ " upon",
+ &sei);
}
vc_cleanup(&p->vc);
}
@@ -114,6 +119,14 @@
{
struct semaphore_info* p;
+ if (s_trace_semaphore)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] semaphore_init 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ semaphore);
+ }
tl_assert(semaphore_get(semaphore) == 0);
p = semaphore_get_or_allocate(semaphore, size);
p->value = value;
@@ -123,6 +136,17 @@
/** Called after sem_destroy(). */
void semaphore_destroy(struct semaphore_info* const p)
{
+ tl_assert(p);
+
+ if (s_trace_semaphore)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] semaphore_destroy 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ p->a1);
+ }
+
drd_clientobj_remove(p->a1, ClientSemaphore);
}
@@ -134,7 +158,11 @@
p = semaphore_get_or_allocate(semaphore, size);
if (s_trace_semaphore)
{
- VG_(message)(Vg_UserMsg, "semaphore_pre_wait(0x%lx, %d)", semaphore, size);
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] semaphore_pre_wait 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ semaphore);
}
tl_assert(p);
tl_assert(p->waiters >= 0);
@@ -154,7 +182,11 @@
p = semaphore_get(semaphore);
if (s_trace_semaphore)
{
- VG_(message)(Vg_UserMsg, "semaphore_post_wait(0x%lx, %d)", semaphore);
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] semaphore_post_wait 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ semaphore);
}
tl_assert(p->waiters > 0);
p->waiters--;
@@ -162,7 +194,12 @@
tl_assert(p->value >= 0);
if (p->value == 0)
{
- VG_(message)(Vg_UserMsg, "Invalid semaphore 0x%lx", semaphore);
+ SemaphoreErrInfo sei = { semaphore };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ SemaphoreErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Invalid semaphore",
+ &sei);
return;
}
p->value--;
@@ -178,6 +215,14 @@
{
struct semaphore_info* p;
+ if (s_trace_semaphore)
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] semaphore_post 0x%lx",
+ VG_(get_running_tid)(),
+ thread_get_running_tid(),
+ semaphore);
+ }
p = semaphore_get_or_allocate(semaphore, size);
p->value++;
if (p->value == 1)
diff --git a/exp-drd/drd_track.h b/exp-drd/drd_track.h
index e5e2368..1c71c84 100644
--- a/exp-drd/drd_track.h
+++ b/exp-drd/drd_track.h
@@ -30,7 +30,7 @@
void drd_pre_mutex_lock(DrdThreadId tid, Addr mutex, const SizeT size,
const MutexT mutex_type);
void drd_post_mutex_lock(DrdThreadId tid, Addr mutex, const SizeT size,
- const MutexT mutex_type);
+ const MutexT mutex_type, const Bool took_lock);
void drd_pre_mutex_unlock(const DrdThreadId tid, const Addr mutex,
const MutexT mutex_type);
diff --git a/exp-drd/tests/Makefile.am b/exp-drd/tests/Makefile.am
index 6e036bf..30657ed 100644
--- a/exp-drd/tests/Makefile.am
+++ b/exp-drd/tests/Makefile.am
@@ -91,8 +91,9 @@
tc19_shadowmem.vgtest \
tc19_shadowmem.stderr.exp \
tc20_verifywrap.vgtest \
- tc20_verifywrap.stderr.exp \
- tc20_verifywrap.stderr.exp2 \
+ tc20_verifywrap.stderr.exp tc20_verifywrap.stderr.exp2 \
+ tc20_verifywrap2.vgtest \
+ tc20_verifywrap2.stderr.exp tc20_verifywrap2.stderr.exp2\
tc21_pthonce.vgtest \
tc21_pthonce.stderr.exp tc21_pthonce.stdout.exp \
tc22_exit_w_lock.vgtest \
diff --git a/exp-drd/tests/tc18_semabuse.stderr.exp b/exp-drd/tests/tc18_semabuse.stderr.exp
index d18786f..dd53466 100644
--- a/exp-drd/tests/tc18_semabuse.stderr.exp
+++ b/exp-drd/tests/tc18_semabuse.stderr.exp
@@ -1,3 +1,6 @@
+Invalid semaphore 0x........
+ at 0x........: sem_wait* (drd_intercepts.c:?)
+ by 0x........: main (tc18_semabuse.c:34)
-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/tc20_verifywrap.stderr.exp2 b/exp-drd/tests/tc20_verifywrap.stderr.exp2
index b5115ca..e4bfdeb 100644
--- a/exp-drd/tests/tc20_verifywrap.stderr.exp2
+++ b/exp-drd/tests/tc20_verifywrap.stderr.exp2
@@ -21,6 +21,18 @@
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)
@@ -41,6 +53,10 @@
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
@@ -58,6 +74,10 @@
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
@@ -67,4 +87,4 @@
Destroying locked mutex: address 0x........, recursion count 1, owner 1.
at 0x........: main (tc20_verifywrap.c:262)
-ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
+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
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.stderr.exp
diff --git a/exp-drd/tests/tc20_verifywrap2.stderr.exp2 b/exp-drd/tests/tc20_verifywrap2.stderr.exp2
new file mode 100644
index 0000000..a05efce
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.stderr.exp2
@@ -0,0 +1,151 @@
+
+
+
+------ This is output for >= glibc 2.4 ------
+
+---------------- pthread_create/join ----------------
+
+[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
+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........
+[1/1] mutex_init mutex 0x........
+[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] mutex_init invalid mutex 0x........
+[1/1] post_mutex_lock invalid mutex 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 invalid mutex 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 invalid mutex 0x........ rc 0 owner 0
+
+Invalid mutex
+ at 0x........: pthread_mutex_timedlock (drd_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:121)
+[1/1] mutex_unlock invalid mutex 0x........ rc 0
+
+Invalid mutex
+ at 0x........: pthread_mutex_unlock (drd_intercepts.c:?)
+ by 0x........: main (tc20_verifywrap.c:125)
+
+Mutex not locked: address 0x........, recursion count 0, owner 0.
+ 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] mutex_destroy invalid mutex 0x........
+[1/1] mutex_destroy invalid mutex 0x........
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 1
+[1/1] post_mutex_lock recursive mutex 0x........ rc 0 owner 1
+[1/1] mutex_unlock recursive mutex 0x........ rc 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/tc20_verifywrap2.vgtest b/exp-drd/tests/tc20_verifywrap2.vgtest
new file mode 100644
index 0000000..d7223f2
--- /dev/null
+++ b/exp-drd/tests/tc20_verifywrap2.vgtest
@@ -0,0 +1,2 @@
+prog: tc20_verifywrap
+vgopts: --trace-mutex=yes --trace-cond=yes --trace-semaphore=yes