@@ -264,8 +264,9 @@ void ha_backtrace_to_stderr(void)
264264 * indicate the requesting one. Any stuck thread is also prefixed with a '>'.
265265 * The caller is responsible for atomically setting up the thread's dump buffer
266266 * to point to a valid buffer with enough room. Output will be truncated if it
267- * does not fit. When the dump is complete, the dump buffer will be switched to
268- * (void*)0x1 that the caller must turn to 0x0 once the contents are collected.
267+ * does not fit. When the dump is complete, the dump buffer will have bit 0 set
268+ * to 1 to tell the caller it's done, and the caller will then change that value
269+ * to indicate it's done once the contents are collected.
269270 */
270271void ha_thread_dump_one (int thr , int from_signal )
271272{
@@ -347,18 +348,19 @@ void ha_thread_dump_one(int thr, int from_signal)
347348 }
348349 leave :
349350 /* end of dump, setting the buffer to 0x1 will tell the caller we're done */
350- HA_ATOMIC_STORE ( & ha_thread_ctx [thr ].thread_dump_buffer , ( void * ) 0x1UL );
351+ HA_ATOMIC_OR (( ulong * ) & ha_thread_ctx [thr ].thread_dump_buffer , 0x1UL );
351352}
352353
353354/* Triggers a thread dump from thread <thr>, either directly if it's the
354355 * current thread or if thread dump signals are not implemented, or by sending
355356 * a signal if it's a remote one and the feature is supported. The buffer <buf>
356357 * will get the dump appended, and the caller is responsible for making sure
357358 * there is enough room otherwise some contents will be truncated. The function
358- * waits for the called thread to fill the buffer before returning. It does not
359- * release the called thread yet.
359+ * waits for the called thread to fill the buffer before returning (or cancelling
360+ * by reporting NULL). It does not release the called thread yet. It returns a
361+ * pointer to the buffer used if the dump was done, otherwise NULL.
360362 */
361- void ha_thread_dump_fill (struct buffer * buf , int thr )
363+ struct buffer * ha_thread_dump_fill (struct buffer * buf , int thr )
362364{
363365 struct buffer * old = NULL ;
364366
@@ -381,22 +383,32 @@ void ha_thread_dump_fill(struct buffer *buf, int thr)
381383#endif
382384 ha_thread_dump_one (thr , thr != tid );
383385
384- /* now wait for the dump to be done */
385- while (HA_ATOMIC_LOAD (& ha_thread_ctx [thr ].thread_dump_buffer ) != (void * )0x1UL )
386+ /* now wait for the dump to be done (or cancelled) */
387+ while (1 ) {
388+ old = HA_ATOMIC_LOAD (& ha_thread_ctx [thr ].thread_dump_buffer );
389+ if ((ulong )old & 0x1 )
390+ break ;
391+ if (!old )
392+ return old ;
386393 ha_thread_relax ();
394+ }
395+ return (struct buffer * )((ulong )old & ~0x1UL );
387396}
388397
389398/* Indicates to the called thread that the dumped data are collected. It waits
390- * for the dump to be completed if it was not the case.
399+ * for the dump to be completed if it was not the case, and can also leave if
400+ * the pointer is NULL (e.g. if a thread has aborted).
391401 */
392402void ha_thread_dump_done (struct buffer * buf , int thr )
393403{
394404 struct buffer * old ;
395405
396- /* now wait for the dump to be done, and release it */
406+ /* now wait for the dump to be done or cancelled , and release it */
397407 do {
398408 old = HA_ATOMIC_LOAD (& ha_thread_ctx [thr ].thread_dump_buffer );
399- if (old != (void * )0x1UL ) {
409+ if (!((ulong )old & 0x1 )) {
410+ if (!old )
411+ return ;
400412 ha_thread_relax ();
401413 continue ;
402414 }
@@ -2106,7 +2118,7 @@ void debug_handler(int sig, siginfo_t *si, void *arg)
21062118 /* first, let's check it's really for us and that we didn't just get
21072119 * a spurious DEBUGSIG.
21082120 */
2109- if (!buf || buf == ( void * )( 0x1UL ) )
2121+ if (!buf || ( ulong ) buf & 0x1UL )
21102122 return ;
21112123
21122124 /* now dump the current state into the designated buffer, and indicate
0 commit comments