From: Willy Tarreau Date: Tue, 6 May 2025 03:11:56 +0000 (+0200) Subject: DEBUG: threads: display held locks in threads dumps X-Git-Tag: v3.2-dev15~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3bb6eea6d56d0328437ed34ac97d4479051ee2c9;p=thirdparty%2Fhaproxy.git DEBUG: threads: display held locks in threads dumps Based on the lock history, we can spot some locks that are still held by checking the last operation that happened on them: if it's not an unlock, then we know the lock is held. In this case we append the list after "locked:" with their label and state like below: U:QUEUE S:IDLE_CONNS U:IDLE_CONNS R:TASK_WQ U:TASK_WQ S:QUEUE S:QUEUE S:QUEUE locked: QUEUE(S) S:IDLE_CONNS U:IDLE_CONNS S:TASK_RQ U:TASK_RQ S:QUEUE U:QUEUE S:IDLE_CONNS locked: IDLE_CONNS(S) R:TASK_WQ S:TASK_WQ R:TASK_WQ S:TASK_WQ R:TASK_WQ S:TASK_WQ R:TASK_WQ locked: TASK_WQ(R) W:STK_TABLE W:STK_TABLE_UPDT U:STK_TABLE_UPDT W:STK_TABLE W:STK_TABLE_UPDT U:STK_TABLE_UPDT W:STK_TABLE W:STK_TABLE_UPDT locked: STK_TABLE(W) STK_TABLE_UPDT(W) The format is slightly different (label(status)) so as to easily differentiate them visually from the history. --- diff --git a/src/debug.c b/src/debug.c index 1d6b30a7a..f92b5ff80 100644 --- a/src/debug.c +++ b/src/debug.c @@ -355,7 +355,8 @@ void ha_thread_dump_one(struct buffer *buf, int is_caller) #if defined(USE_THREAD) && ((DEBUG_THREAD > 0) || defined(DEBUG_FULL)) /* List the lock history */ if (th_ctx->lock_history) { - int lkh, lkl; + int lkh, lkl, lbl; + int done; chunk_appendf(buf, " lock_hist:"); for (lkl = 7; lkl >= 0; lkl--) { @@ -365,6 +366,29 @@ void ha_thread_dump_one(struct buffer *buf, int is_caller) chunk_appendf(buf, " %c:%s", "URSW"[lkh & 3], lock_label((lkh >> 2) - 1)); } + + /* now rescan the list to only show those that remain */ + done = 0; + for (lbl = 0; lbl < LOCK_LABELS; lbl++) { + /* find the latest occurrence of each label */ + for (lkl = 0; lkl < 8; lkl++) { + lkh = (th_ctx->lock_history >> (lkl * 8)) & 0xff; + if (!lkh) + continue; + if ((lkh >> 2) == lbl) + break; + } + if (lkl == 8) // not found + continue; + if ((lkh & 3) == _LK_UN) + continue; + if (!done) + chunk_appendf(buf, " locked:"); + chunk_appendf(buf, " %s(%c)", + lock_label((lkh >> 2) - 1), + "URSW"[lkh & 3]); + done++; + } chunk_appendf(buf, "\n"); } #endif