From: Willy Tarreau Date: Thu, 17 Apr 2025 08:28:37 +0000 (+0200) Subject: BUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill() X-Git-Tag: v3.2-dev11~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b56839455c7f45ae58954e1eb3873a3725899dc;p=thirdparty%2Fhaproxy.git BUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill() The function must make sure to return NULL for foreign threads and the local buffer for the current thread in this case, otherwise panics (and sometimes even warnings) will segfault when USE_THREAD_DUMP is disabled. Let's slightly re-arrange the function to reduce the #if/else since we have to specifically handle the case of !USE_THREAD_DUMP anyway. This needs to be backported wherever b8adef065d ("MEDIUM: debug: on panic, make the target thread automatically allocate its buf") was backported (at least 2.8). --- diff --git a/src/debug.c b/src/debug.c index 29339413f..273c59ce1 100644 --- a/src/debug.c +++ b/src/debug.c @@ -386,6 +386,7 @@ struct buffer *ha_thread_dump_fill(struct buffer *buf, int thr) { struct buffer *old = NULL; +#ifdef USE_THREAD_DUMP /* A thread that's currently dumping other threads cannot be dumped, or * it will very likely cause a deadlock. */ @@ -404,14 +405,12 @@ struct buffer *ha_thread_dump_fill(struct buffer *buf, int thr) old = NULL; } while (!HA_ATOMIC_CAS(&ha_thread_ctx[thr].thread_dump_buffer, &old, buf)); -#ifdef USE_THREAD_DUMP /* asking the remote thread to dump itself allows to get more details * including a backtrace. */ if (thr != tid) ha_tkill(thr, DEBUGSIG); else -#endif ha_thread_dump_one(thr, thr != tid); /* now wait for the dump to be done (or cancelled) */ @@ -426,6 +425,20 @@ struct buffer *ha_thread_dump_fill(struct buffer *buf, int thr) } ha_thread_relax(); } +#else /* !USE_THREAD_DUMP below, we're on the target thread */ + /* when thread-dump is not supported, we can only dump our own thread */ + if (thr != tid) + return NULL; + + /* the buffer might not be valid in case of a panic, since we + * have to allocate it ourselves in this case. + */ + if ((ulong)buf == 0x2UL) + buf = get_trash_chunk(); + HA_ATOMIC_STORE(&th_ctx->thread_dump_buffer, buf); + old = buf; + ha_thread_dump_one(tid, 0); +#endif return (struct buffer *)((ulong)old & ~0x1UL); }