How to set the name of a thread in Linux pthreads?
Asked Answered
O

3

70

Is there any way of setting the name of a thread in Linux?

My main purpose is it would be helpful while debugging, and also nice if that name was exposed through e.g. /proc/$PID/task/$TID/...

Occidentalize answered 3/3, 2010 at 8:36 Comment(5)
Could you please tell possibly with some examples how names can be useful in debugging?Kelila
@skwllsp: So you can more easily identify the thread?Quarterdeck
Threads names definitely help when you have programs with a large set of different threads each doing something specific (like a pipeline setup where each thread does some part of a processing task to each packet). I have seen the need for this. Good debug tools with OS awareness should also be able to display these names, not clear how many of the debuggers out there do that today.Aspect
Duplicate of #778585Stercoraceous
Possibly a better solution as the default functions do not reflect the name in the /proc/self/comm file of the thread. Or it duplicates the last name set, which is as useless as not having it. Directly writing to the comm file is allowed and works as expected for a ll tools (such as htop and ps).Upu
Q
40

Use the prctl(2) function with the option PR_SET_NAME (see the docs).

Note that old versions of the docs are a bit confusing. They say

Set the process name for the calling process

but since threads are light weight processes (LWP) on Linux, one thread is one process in this case.

You can see the thread name with ps -o cmd or with:

cat /proc/$PID/task/$TID/comm

or in between the () of cat /proc/$PID/task/$TID/stat:

4223 (kjournald) S 1 1 1 0...

or from GDB info threads between double quotes:

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  
Quarterdeck answered 3/3, 2010 at 8:43 Comment(5)
Note that the actual thread names will be in /proc/$PID/tasks/$TID/statFollowup
@Followup Even though they're not visible in the directory listing of /proc, threads are accessible via /proc/$TID (due to being the same as processes, basically).Unheardof
@nos, at least in kernel version 3.2.0, it's /proc/$PID/task/$TID/stat (no s on tasks)Soler
I'll leave it here for completeness, possible pitfall with changing main thread name: lists.linuxfoundation.org/pipermail/bugme-new/2008-October/…Unbrace
@AndrewWagner Even though threads are not listed in a directory listing of /proc/, if you access /proc/$TID/ you can still get the thread's information.Ciceronian
L
128

As of glibc v2.12, you can use pthread_setname_np and pthread_getname_np to set/get the thread name.

These interfaces are available on a few other POSIX systems (BSD, QNX, Mac) in various slightly different forms.

Setting the name will be something like this:

#include <pthread.h>  // or maybe <pthread_np.h> for some OSes

// Linux
int pthread_setname_np(pthread_t thread, const char *name);

// NetBSD: name + arg work like printf(name, arg)
int pthread_setname_np(pthread_t thread, const char *name, void *arg);

// FreeBSD & OpenBSD: function name is slightly different, and has no return value
void pthread_set_name_np(pthread_t tid, const char *name);

// Mac OS X: must be set from within the thread (can't specify thread ID)
int pthread_setname_np(const char*);

And you can get the name back:

#include <pthread.h>  // or <pthread_np.h> ?

// Linux, NetBSD:
int pthread_getname_np(pthread_t th, char *buf, size_t len);
// some implementations don't have a safe buffer (see MKS/IBM below)
int pthread_getname_np(pthread_t thread, const char **name);
int pthread_getname_np(pthread_t thread, char *name);

// FreeBSD & OpenBSD: dont' seem to have getname/get_name equivalent?
// but I'd imagine there's some other mechanism to read it directly for say gdb

// Mac OS X:
int pthread_getname_np(pthread_t, char*, size_t);

As you can see it's not completely portable between POSIX systems, but as far as I can tell across linux it should be consistent. Apart from Mac OS X (where you can only do it from within the thread), the others are at least simple to adapt for cross-platform code.

Sources:

Lock answered 3/11, 2011 at 3:31 Comment(5)
I don't get what the point of pthread_set_name_np() is on BSD if the name cannot be retrieved...?Piety
@kralyk, yeah its not so useful for in-app use, but i suspect it can be retrieved through some other mechanism (e.g. read from memory directly by gdb or something?)... FWIW NetBSD is compatible with the Linux interfaces (and slightly extends them with printf-like usage)Lock
@Lock - Where is a constant, defining the maximum length of the name? I don't see any docs about itHomotaxis
@Piety I think it'll be useful while debugging with gdb or in top -HColdblooded
I'm looking at the NetBSD doccumentation for pthread_setname_np(), and I'm confused about one of the parameters for it. Could you help explain what the void * arg parameter represents? I know that it's a pointer but I'm not sure what "argument used with name" means here. Could I just pass nullptr? Why or why not?Maihem
Q
40

Use the prctl(2) function with the option PR_SET_NAME (see the docs).

Note that old versions of the docs are a bit confusing. They say

Set the process name for the calling process

but since threads are light weight processes (LWP) on Linux, one thread is one process in this case.

You can see the thread name with ps -o cmd or with:

cat /proc/$PID/task/$TID/comm

or in between the () of cat /proc/$PID/task/$TID/stat:

4223 (kjournald) S 1 1 1 0...

or from GDB info threads between double quotes:

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  
Quarterdeck answered 3/3, 2010 at 8:43 Comment(5)
Note that the actual thread names will be in /proc/$PID/tasks/$TID/statFollowup
@Followup Even though they're not visible in the directory listing of /proc, threads are accessible via /proc/$TID (due to being the same as processes, basically).Unheardof
@nos, at least in kernel version 3.2.0, it's /proc/$PID/task/$TID/stat (no s on tasks)Soler
I'll leave it here for completeness, possible pitfall with changing main thread name: lists.linuxfoundation.org/pipermail/bugme-new/2008-October/…Unbrace
@AndrewWagner Even though threads are not listed in a directory listing of /proc/, if you access /proc/$TID/ you can still get the thread's information.Ciceronian
C
6

You can implement this yourself by creating a dictionary mapping pthread_t to std::string, and then associate the result of pthread_self() with the name that you want to assign to the current thread. Note that, if you do that, you will need to use a mutex or other synchronization primitive to prevent multiple threads from concurrently modifying the dictionary (unless your dictionary implementation already does this for you). You could also use thread-specific variables (see pthread_key_create, pthread_setspecific, pthread_getspecific, and pthread_key_delete) in order to save the name of the current thread; however, you won't be able to access the names of other threads if you do that (whereas, with a dictionary, you can iterate over all thread id/name pairs from any thread).

Colonialism answered 3/3, 2010 at 9:14 Comment(6)
Note that this solution is portable across Linux, Mac OS X, and all systems that conform to the Single UNIX Specification. (A suggestion posted by Aaron Digulla to use "prctl" is not portable).Colonialism
This seems like a really bad idea, and people shouldn't do it.Heelpiece
And how can you see it from outside the APP? like in ps, or top?Auliffe
This comment was a bit outdated. dfrogsplat's answer is the best one, given that it is now supported across platforms.Colonialism
+1 - still useful in embedded Linux with obsolete or exotic C libraries.Extracanonical
In C, you now have _Thread_local (since C11). That way the compiler does the heavy lifting work for you. There is also a thread_local macro (to use the same name as in C++11)Upu

© 2022 - 2024 — McMap. All rights reserved.