diff --git a/include/common/hathreads.h b/include/common/hathreads.h index b3fff40836..82357d5bd3 100644 --- a/include/common/hathreads.h +++ b/include/common/hathreads.h @@ -170,6 +170,11 @@ static inline void ha_set_tid(unsigned int tid) ti = &ha_thread_info[tid]; } +static inline unsigned long ha_get_pthread_id(unsigned int thr) +{ + return 0; +} + static inline void ha_thread_relax(void) { #if _POSIX_PRIORITY_SCHEDULING @@ -483,6 +488,37 @@ static inline void ha_set_tid(unsigned int data) ti = &ha_thread_info[tid]; } +/* Retrieves the opaque pthread_t of thread cast to an unsigned long long + * since POSIX took great care of not specifying its representation, making it + * hard to export for post-mortem analysis. For this reason we copy it into a + * union and will use the smallest scalar type at least as large as its size, + * which will keep endianness and alignment for all regular sizes. As a last + * resort we end up with a long long ligned to the first bytes in memory, which + * will be endian-dependent if pthread_t is larger than a long long (not seen + * yet). + */ +static inline unsigned long long ha_get_pthread_id(unsigned int thr) +{ + union { + pthread_t t; + unsigned long long ll; + unsigned int i; + unsigned short s; + unsigned char c; + } u; + + memset(&u, 0, sizeof(u)); + u.t = ha_thread_info[thr].pthread; + + if (sizeof(u.t) <= sizeof(u.c)) + return u.c; + else if (sizeof(u.t) <= sizeof(u.s)) + return u.s; + else if (sizeof(u.t) <= sizeof(u.i)) + return u.i; + return u.ll; +} + static inline void ha_thread_relax(void) { #if _POSIX_PRIORITY_SCHEDULING diff --git a/src/debug.c b/src/debug.c index dd13aa4f74..a94fd28301 100644 --- a/src/debug.c +++ b/src/debug.c @@ -58,9 +58,10 @@ void ha_thread_dump(struct buffer *buf, int thr, int calling_tid) int stuck = !!(ha_thread_info[thr].flags & TI_FL_STUCK); chunk_appendf(buf, - "%c%cThread %-2u: act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n" + "%c%cThread %-2u: id=0x%lx act=%d glob=%d wq=%d rq=%d tl=%d tlsz=%d rqsz=%d\n" " stuck=%d prof=%d", (thr == calling_tid) ? '*' : ' ', stuck ? '>' : ' ', thr + 1, + ha_get_pthread_id(thr), thread_has_tasks(), !!(global_tasks_mask & thr_bit), !eb_is_empty(&task_per_thread[thr].timers),