From b4a29c0a0fbd25a2de8a16b3049677fb2b8e1645 Mon Sep 17 00:00:00 2001 From: Dave Hart Date: Mon, 7 Mar 2011 23:08:42 -0500 Subject: [PATCH] Add a magic number to debug_locks to better catch lock-coding errors. Original description by Dave Hart: [This patch contains] the addition of a signature field to debug_lock initialized by the alloc routine and verified by the rest, to catch invalid lock pointers sooner. That helped me track down a nasty problem I had before adding the time.h include to libevent-internal.h, where different .c files had different ideas of whether event_base had a tod_tv_cache member depending on which included time.h before libevent-internal.h. --- evthread.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/evthread.c b/evthread.c index c96c6fd9..d9c54787 100644 --- a/evthread.c +++ b/evthread.c @@ -109,7 +109,10 @@ evthread_set_condition_callbacks(const struct evthread_condition_callbacks *cbs) return 0; } +#define DEBUG_LOCK_SIG 0xdeb0b10c + struct debug_lock { + unsigned signature; unsigned locktype; unsigned long held_by; /* XXXX if we ever use read-write locks, we will need a separate @@ -133,6 +136,7 @@ debug_lock_alloc(unsigned locktype) } else { result->lock = NULL; } + result->signature = DEBUG_LOCK_SIG; result->locktype = locktype; result->count = 0; result->held_by = 0; @@ -145,6 +149,7 @@ debug_lock_free(void *lock_, unsigned locktype) struct debug_lock *lock = lock_; EVUTIL_ASSERT(lock->count == 0); EVUTIL_ASSERT(locktype == lock->locktype); + EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature); if (_original_lock_fns.free) { _original_lock_fns.free(lock->lock, lock->locktype|EVTHREAD_LOCKTYPE_RECURSIVE); @@ -157,6 +162,7 @@ debug_lock_free(void *lock_, unsigned locktype) static void evthread_debug_lock_mark_locked(unsigned mode, struct debug_lock *lock) { + EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature); ++lock->count; if (!(lock->locktype & EVTHREAD_LOCKTYPE_RECURSIVE)) EVUTIL_ASSERT(lock->count == 1); @@ -189,12 +195,15 @@ debug_lock_lock(unsigned mode, void *lock_) static void evthread_debug_lock_mark_unlocked(unsigned mode, struct debug_lock *lock) { + EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature); if (lock->locktype & EVTHREAD_LOCKTYPE_READWRITE) EVUTIL_ASSERT(mode & (EVTHREAD_READ|EVTHREAD_WRITE)); else EVUTIL_ASSERT((mode & (EVTHREAD_READ|EVTHREAD_WRITE)) == 0); if (_evthread_id_fn) { - EVUTIL_ASSERT(lock->held_by == _evthread_id_fn()); + unsigned long me; + me = _evthread_id_fn(); + EVUTIL_ASSERT(lock->held_by == me); if (lock->count == 1) lock->held_by = 0; } @@ -218,6 +227,7 @@ debug_cond_wait(void *_cond, void *_lock, const struct timeval *tv) { int r; struct debug_lock *lock = _lock; + EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature); EVLOCK_ASSERT_LOCKED(_lock); evthread_debug_lock_mark_unlocked(0, lock); r = _original_cond_fns.wait_condition(_cond, lock->lock, tv);