OVS_NO_THREAD_SAFETY_ANALYSIS \
     { \
         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
-        int error = pthread_##TYPE##_##FUN(&l->lock); \
+        int error; \
+ \
+        /* Verify that 'l' was initialized. */ \
+        ovs_assert(l->where); \
+ \
+        error = pthread_##TYPE##_##FUN(&l->lock); \
         if (OVS_UNLIKELY(error)) { \
             ovs_abort(error, "pthread_%s_%s failed", #TYPE, #FUN); \
         } \
         l->where = where; \
-    }
+ }
 LOCK_FUNCTION(mutex, lock);
 LOCK_FUNCTION(rwlock, rdlock);
 LOCK_FUNCTION(rwlock, wrlock);
         OVS_NO_THREAD_SAFETY_ANALYSIS \
     { \
         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
-        int error = pthread_##TYPE##_##FUN(&l->lock); \
+        int error; \
+ \
+        /* Verify that 'l' was initialized. */ \
+        ovs_assert(l->where); \
+ \
+        error = pthread_##TYPE##_##FUN(&l->lock); \
         if (OVS_UNLIKELY(error) && error != EBUSY) { \
             ovs_abort(error, "pthread_%s_%s failed", #TYPE, #FUN); \
         } \
 TRY_LOCK_FUNCTION(rwlock, tryrdlock);
 TRY_LOCK_FUNCTION(rwlock, trywrlock);
 
-#define UNLOCK_FUNCTION(TYPE, FUN) \
+#define UNLOCK_FUNCTION(TYPE, FUN, WHERE) \
     void \
     ovs_##TYPE##_##FUN(const struct ovs_##TYPE *l_) \
         OVS_NO_THREAD_SAFETY_ANALYSIS \
     { \
         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
         int error; \
-        l->where = NULL; \
+ \
+        /* Verify that 'l' was initialized. */ \
+        ovs_assert(l->where); \
+ \
+        l->where = WHERE; \
         error = pthread_##TYPE##_##FUN(&l->lock); \
         if (OVS_UNLIKELY(error)) { \
             ovs_abort(error, "pthread_%s_%sfailed", #TYPE, #FUN); \
         } \
     }
-UNLOCK_FUNCTION(mutex, unlock);
-UNLOCK_FUNCTION(mutex, destroy);
-UNLOCK_FUNCTION(rwlock, unlock);
-UNLOCK_FUNCTION(rwlock, destroy);
+UNLOCK_FUNCTION(mutex, unlock, "<unlocked>");
+UNLOCK_FUNCTION(mutex, destroy, NULL);
+UNLOCK_FUNCTION(rwlock, unlock, "<unlocked>");
+UNLOCK_FUNCTION(rwlock, destroy, NULL);
 
 #define XPTHREAD_FUNC1(FUNCTION, PARAM1)                \
     void                                                \
     pthread_mutexattr_t attr;
     int error;
 
-    l->where = NULL;
+    l->where = "<unlocked>";
     xpthread_mutexattr_init(&attr);
     xpthread_mutexattr_settype(&attr, type);
     error = pthread_mutex_init(&l->lock, &attr);
     pthread_rwlockattr_t attr;
     int error;
 
-    l->where = NULL;
+    l->where = "<unlocked>";
 
     xpthread_rwlockattr_init(&attr);
 #ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
 
 /* Mutex. */
 struct OVS_LOCKABLE ovs_mutex {
     pthread_mutex_t lock;
-    const char *where;
+    const char *where;          /* NULL if and only if uninitialized. */
 };
 
 /* "struct ovs_mutex" initializer. */
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-#define OVS_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, NULL }
+#define OVS_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, \
+                                "<unlocked>" }
 #else
-#define OVS_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, NULL }
+#define OVS_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, "<unlocked>" }
 #endif
 
 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
  *       than exposing them only to porters. */
 struct OVS_LOCKABLE ovs_rwlock {
     pthread_rwlock_t lock;
-    const char *where;
+    const char *where;          /* NULL if and only if uninitialized. */
 };
 
 /* Initializer. */
 #ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
 #define OVS_RWLOCK_INITIALIZER \
-        { PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, NULL }
+        { PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, "<unlocked>" }
 #else
-#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, NULL }
+#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "<unlocked>" }
 #endif
 
 /* ovs_rwlock functions analogous to pthread_rwlock_*() functions.