]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tinfo: keep a copy of the pointer to the thread dump buffer
authorWilly Tarreau <w@1wt.eu>
Thu, 10 Apr 2025 06:29:39 +0000 (08:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 17 Apr 2025 14:25:47 +0000 (16:25 +0200)
Instead of using the thread dump buffer for post-mortem analysis, we'll
keep a copy of the assigned pointer whenever it's used, even for warnings
or "show threads". This will offer more opportunities to figure from a
core what happened, and will give us more freedom regarding the value of
the thread_dump_buffer itself. For example, even at the end of the dump
when the pointer is reset, the last used buffer is now preserved.

doc/internals/watchdog.txt
include/haproxy/tinfo-t.h
src/debug.c

index cb212b79092983966b0a1b9cf527e2f93fb39b40..b2faa5140ba7bb7ecd748402c7406bfbdddcb70f 100644 (file)
@@ -85,6 +85,12 @@ to point to the target buffer. The thread_dump_buffer has 4 possible values:
     will keep their own copy of their own dump so that it can be later found in
     the core file for inspection.
 
+A copy of the last valid thread_dump_buffer used is kept in last_dump_buffer,
+for easier post-mortem analysis. This one may be NULL or even invalid, but
+usually during a panic it will be valid, and may reveal useful hints even if it
+still contains the dump of the last warning. Usually this will point to a trash
+buffer or to stack area.
+
 ha_thread_dump_fill() then either directly calls ha_thread_dump_one() if the
 target thread is the current thread, or sends the target thread DEBUGSIG
 (SIGURG) if it's a different thread. This signal is initialized at boot time
index 95604b0f563fa66038f7c93ccad1dddda13efa2e..229f0a4c2682c76f12f4762d599dd1eeb14ddc52 100644 (file)
@@ -188,6 +188,7 @@ struct thread_ctx {
        unsigned long long out_bytes;           /* total #of bytes emitted */
        unsigned long long spliced_out_bytes;   /* total #of bytes emitted though a kernel pipe */
        struct buffer *thread_dump_buffer;      /* NULL out of dump, 0x02=to alloc, valid during a dump, |0x01 once done */
+       struct buffer *last_dump_buffer;        /* Copy of last buffer used for a dump; may be NULL or invalid; for post-mortem only */
        unsigned long long total_streams;       /* Total number of streams created on this thread */
        unsigned int stream_cnt;                /* Number of streams attached to this thread */
 
index d4a61f27bcc3c1a509dac5377355706691307831..8a5a07f8908a9383f6a54942384e244c90dc6f4a 100644 (file)
@@ -319,6 +319,9 @@ void ha_thread_dump_one(int thr, int from_signal)
        unsigned long long n = now_cpu_time_thread(thr);
        int stuck = !!(ha_thread_ctx[thr].flags & TH_FL_STUCK);
 
+       /* keep a copy of the dump pointer for post-mortem analysis */
+       HA_ATOMIC_STORE(&ha_thread_ctx[thr].last_dump_buffer, buf);
+
        chunk_appendf(buf,
                      "%c%cThread %-2u: id=0x%llx act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n"
                      "     %2u/%-2u   stuck=%d prof=%d",