On Mon, Aug 03, 2026 at 11:38:40AM +0200, Willy Tarreau wrote:
> Hello Abhishek,
>
> On Wed, Jul 29, 2026 at 10:31:28PM -0500, Abhishek Chanda wrote:
> > Hello all,
> >
> > We run haproxy in front of postgres. While debugging some connection issues
> > with linux tools, we noticed that all the threads were using the same name.
> > This made debugging difficult. Attaching a patch that changes haproxy to
> > set unique thread names. I tested this manually on OSX. This should make
> > debugging this much easier. Please let me know if anything should be
> > changed.
>
> Thanks for this, this is indeed quite interesting.
>
> However I noticed a problem with it: it also changes the name seen by
> some tools like "killall", making it impossible to touch the started
> command:
>
> $ ./haproxy -db -f foo.cfg &
> [1] 31906
> $ pgrep '^haproxy$'
> $ pgrep '^haproxy-1$'
> 31906
> $ pgrep '^haproxy-2$'
> $ killall haproxy
> haproxy: no process found
> $ killall haproxy-1
> [1]+ Terminated ./haproxy -db -f foo.cfg
> $
>
> Worse, it even affects processes started under different names:
>
> $ ./haterm -L :8001 &
> [1] 32250
> $ killall haterm
> haterm: no process found
> $ killall haterm-1
> haterm-1: no process found
> $ killall haproxy-1
> $
> [1]+ Terminated ./haterm -L :8001
>
> So I guess that the right thing to do would be to use
> pthread_getname_np() to retrieve the first thread's name, and use that
> as a radix to append "-%d" for threads 2-N. This would leave thread 1's
> name unchanged (the exact same that was used to start the program),
> which would permit to continue to manage the process, and would rename
> other ones.
So I tried this and it gets the job done fine:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2562 willy 20 0 301744 5172 4252 R 92.3 0.0 0:06.04 h1load
2563 willy 20 0 301744 5172 4252 R 92.3 0.0 0:06.11 h1load
2564 willy 20 0 301744 5172 4252 R 91.3 0.0 0:06.07 h1load
2561 willy 20 0 301744 5172 4252 R 89.4 0.0 0:06.10 h1load
2555 willy 20 0 558276 29984 11596 R 47.1 0.2 0:02.99 haproxy-5
2546 willy 20 0 558276 29984 11596 R 46.2 0.2 0:03.03 haproxy
2553 willy 20 0 558276 29984 11596 R 46.2 0.2 0:03.05 haproxy-3
2556 willy 20 0 558276 29984 11596 R 46.2 0.2 0:03.01 haproxy-6
2558 willy 20 0 558276 29984 11596 R 46.2 0.2 0:02.99 haproxy-8
2557 willy 20 0 558276 29984 11596 R 45.2 0.2 0:03.10 haproxy-7
2552 willy 20 0 558276 29984 11596 R 44.2 0.2 0:03.04 haproxy-2
2554 willy 20 0 558276 29984 11596 R 41.3 0.2 0:02.91 haproxy-4
$ killall haproxy
[1]+ Terminated ./haproxy -db -f foo.cfg
I'm attaching the patch on top of yours (only for linux, I have not
touched the mac-os part since I can't test it). Also, I'd prefer to
see the function moved to thread.c instead of haproxy.c as it's really
specific to threads.
> By the way, I noticed that pthread_setname_np() and pthread_getname_np()
> also exist on freebsd, and seem to work exactly like Linux, so it might
> be worth adding FreeBSD to the #ifdef list.
I've also enabled the test of FreeBSD in the patch. I can test it if
you want.
> Another point, I've just tried to get gdb to report the thread names
> but it doesn't (linux + gdb 16.3 here):
>
> [Current thread is 1 (Thread 0x7fec6f8529c0 (LWP 468))]
> (gdb) info thread
> Id Target Id Frame
> * 1 Thread 0x7fec6f8529c0 (LWP 468) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 2 Thread 0x7fec677fe640 (LWP 481) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 3 Thread 0x7fec67fff640 (LWP 480) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 4 Thread 0x7fec66ffd640 (LWP 482) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 5 Thread 0x7fec6f3a8640 (LWP 475) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 6 Thread 0x7fec6dfba640 (LWP 477) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 7 Thread 0x7fec6cf56640 (LWP 479) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
> 8 Thread 0x7fec6d7b9640 (LWP 478) 0x00007fec6f4b47d6 in epoll_wait ()
> from /lib64/libc.so.6
>
> I don't know if you found a way to make this work. It's also said that
> prctl(PR_SET_NAME) would be used but I haven't tried it.
I checked the doc, and prctl() does the exact same thing as
pthread_setname_np().
Willy
>From a0342f2fec3496fd44d0edbe5bf71ecb440fbf33 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <[email protected]>
Date: Mon, 3 Aug 2026 12:03:51 +0200
Subject: WIP: use pthread_getname_np() to get the name and rename threads 2+
---
src/haproxy.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/src/haproxy.c b/src/haproxy.c
index 0c23820015..3c1afab008 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -3110,16 +3110,29 @@ void run_poll_loop()
_HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_IN_LOOP);
}
-#if defined(USE_THREAD) && (defined(__linux__) || defined(__APPLE__))
+#if defined(USE_THREAD) && (defined(__linux__) || defined(__APPLE__) ||
defined(__FreeBSD__))
static void set_thread_name(void)
{
- char name[16];
+ char name[20];
- snprintf(name, sizeof(name), "haproxy-%u", tid + 1);
#if defined(__APPLE__)
- pthread_setname_np(name);
+ if (tid > 0) {
+ snprintf(name, sizeof(name), "haproxy-%u", tid + 1);
+ pthread_setname_np(name);
+ }
#else
- pthread_setname_np(pthread_self(), name);
+ if (tid > 0) {
+ int len;
+
+ if (pthread_getname_np(pthread_self(), name, sizeof(name)) != 0)
+ return;
+ len = strlen(name);
+
+ if (len < sizeof(name)) {
+ snprintf(name + len, sizeof(name) - len, "-%u", tid +
1);
+ pthread_setname_np(pthread_self(), name);
+ }
+ }
#endif
}
#else
--
2.35.3