MINOR: tinfo: keep a copy of the pointer to the thread dump buffer

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.
This commit is contained in:
Willy Tarreau 2025-04-10 08:29:39 +02:00
parent d20e9cad67
commit 6d8a523d14
3 changed files with 10 additions and 0 deletions

View 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 will keep their own copy of their own dump so that it can be later found in
the core file for inspection. 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 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 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 (SIGURG) if it's a different thread. This signal is initialized at boot time

View File

@ -188,6 +188,7 @@ struct thread_ctx {
unsigned long long out_bytes; /* total #of bytes emitted */ unsigned long long out_bytes; /* total #of bytes emitted */
unsigned long long spliced_out_bytes; /* total #of bytes emitted though a kernel pipe */ 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 *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 long long total_streams; /* Total number of streams created on this thread */
unsigned int stream_cnt; /* Number of streams attached to this thread */ unsigned int stream_cnt; /* Number of streams attached to this thread */

View File

@ -319,6 +319,9 @@ void ha_thread_dump_one(int thr, int from_signal)
unsigned long long n = now_cpu_time_thread(thr); unsigned long long n = now_cpu_time_thread(thr);
int stuck = !!(ha_thread_ctx[thr].flags & TH_FL_STUCK); 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, chunk_appendf(buf,
"%c%cThread %-2u: id=0x%llx act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n" "%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", " %2u/%-2u stuck=%d prof=%d",