]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR debug: fix !USE_THREAD_DUMP in ha_thread_dump_fill()
authorWilly Tarreau <w@1wt.eu>
Thu, 17 Apr 2025 08:28:37 +0000 (10:28 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 17 Apr 2025 14:25:47 +0000 (16:25 +0200)
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).

src/debug.c

index 29339413f22e1ec127e42365e7ae4e2fbe3d8e6a..273c59ce19a40a4b38757387591cfb68ca57b891 100644 (file)
@@ -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);
 }