Mercurial > libjeffpc
changeset 765:f3ee19f4d8d0
synch: sanity check held type for lock destroy/lock/unlock
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Thu, 25 Jul 2019 13:36:54 -0400 |
parents | ac06f315317e |
children | 041bab629917 |
files | synch.c |
diffstat | 1 files changed, 34 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/synch.c Thu Jul 25 13:12:00 2019 -0400 +++ b/synch.c Thu Jul 25 13:36:54 2019 -0400 @@ -114,6 +114,23 @@ held_stack_count--; } +/* + * Sanity check that the two synch types are equal. In several places, we + * want to make sure that the held structure's type matches that it truly + * should be. Since this is such an unlikely to fail check, we don't even + * try to make nice user friendly error messages. + * + * The only way this check could fail is if a lock got acquired, then + * re-initialized as a different type of a lock, and then destroyed. E.g., + * if the code acquires a mutex (struct lock), and then tries to destroy the + * same structure as a (struct rwlock). + */ +static inline void sanity_check_held_synch_type(struct held_lock *held, + enum synch_type exp) +{ + VERIFY3U(held->type, ==, exp); +} + #define LOCK_DEP_GRAPH() VERIFY0(pthread_mutex_lock(&lockdep_lock)) #define UNLOCK_DEP_GRAPH() VERIFY0(pthread_mutex_unlock(&lockdep_lock)) @@ -497,10 +514,13 @@ /* check that we're not holding it */ for_each_held_lock(i, held) { - if (held->info == &l->info) { - error_destroy(held, where); - return; - } + if (held->info != &l->info) + continue; + + sanity_check_held_synch_type(held, SYNCH_TYPE_MUTEX); + + error_destroy(held, where); + return; } #endif @@ -524,10 +544,14 @@ /* check for deadlocks & recursive locking */ for_each_held_lock(i, held) { - if ((held->info == &l->info) || (held->info->lc == l->info.lc)) { - error_lock(held, l, where); - return; - } + if ((held->info != &l->info) && (held->info->lc != l->info.lc)) + continue; + + if (held->info == &l->info) + sanity_check_held_synch_type(held, SYNCH_TYPE_MUTEX); + + error_lock(held, l, where); + return; } /* check for circular dependencies */ @@ -564,6 +588,8 @@ if (held->info != &l->info) continue; + sanity_check_held_synch_type(held, SYNCH_TYPE_MUTEX); + held_stack_remove(held); goto out;