From: W.C.A. Wijngaards Date: Mon, 22 Apr 2024 11:42:35 +0000 (+0200) Subject: - Add checklock feature verbose_locking to trace locks and unlocks. X-Git-Tag: release-1.20.0rc1~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5994fb3db502b1b72bf0966330a392dd7e7a1fc7;p=thirdparty%2Funbound.git - Add checklock feature verbose_locking to trace locks and unlocks. --- diff --git a/doc/Changelog b/doc/Changelog index ecb91f28a..fd9d340fb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +22 April 2024: Wouter + - Add checklock feature verbose_locking to trace locks and unlocks. + 15 April 2024: Wouter - Fix #1048: Update ax_pkg_swig.m4 and ax_pthread.m4. - Fix configure, autoconf for #1048. diff --git a/testcode/checklocks.c b/testcode/checklocks.c index 1b5ef282b..d1c877467 100644 --- a/testcode/checklocks.c +++ b/testcode/checklocks.c @@ -68,6 +68,17 @@ static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS]; int check_locking_order = 1; /** the pid of this runset, reasonably unique. */ static pid_t check_lock_pid; +/** + * Should checklocks print a trace of the lock and unlock calls. + * It uses fprintf for that because the log function uses a lock and that + * would loop otherwise. + */ +static int verbose_locking = 0; +/** + * Assume lock 0 0 (create_thread, create_instance), is the log lock and + * do not print for that. Otherwise the output is full of log lock accesses. + */ +static int verbose_locking_not_loglock = 1; /** print all possible debug info on the state of the system */ static void total_debug_info(void); @@ -508,6 +519,9 @@ checklock_rdlock(enum check_lock_type type, struct checked_lock* lock, if(key_deleted) return; + if(verbose_locking && !(verbose_locking_not_loglock && + lock->create_thread == 0 && lock->create_instance == 0)) + fprintf(stderr, "checklock_rdlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line); log_assert(type == check_lock_rwlock); checklock_lockit(type, lock, func, file, line, try_rd, timed_rd, &lock->u.rwlock, 0, 0); @@ -528,6 +542,9 @@ checklock_wrlock(enum check_lock_type type, struct checked_lock* lock, if(key_deleted) return; log_assert(type == check_lock_rwlock); + if(verbose_locking && !(verbose_locking_not_loglock && + lock->create_thread == 0 && lock->create_instance == 0)) + fprintf(stderr, "checklock_wrlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line); checklock_lockit(type, lock, func, file, line, try_wr, timed_wr, &lock->u.rwlock, 0, 1); } @@ -565,6 +582,9 @@ checklock_lock(enum check_lock_type type, struct checked_lock* lock, if(key_deleted) return; log_assert(type != check_lock_rwlock); + if(verbose_locking && !(verbose_locking_not_loglock && + lock->create_thread == 0 && lock->create_instance == 0)) + fprintf(stderr, "checklock_lock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line); switch(type) { case check_lock_mutex: checklock_lockit(type, lock, func, file, line, @@ -602,6 +622,10 @@ checklock_unlock(enum check_lock_type type, struct checked_lock* lock, if(lock->hold_count <= 0) lock_error(lock, func, file, line, "too many unlocks"); + if(verbose_locking && !(verbose_locking_not_loglock && + lock->create_thread == 0 && lock->create_instance == 0)) + fprintf(stderr, "checklock_unlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line); + /* store this point as last touched by */ lock->holder = thr; lock->hold_count --;