I've come across some unexpected behaviour with pthread_detach
. Consider the following code:
#include <pthread.h>
int main() {
pthread_detach(0);
}
It's obviously an error (0 is not a valid pthread_t
). When I run this code, the process crashes with a segfault.
The problem is that, according to the man page, it should handle this error and simply return ESRCH (since this should just be a case of "no thread with ID 0 found", right?)
The only undefined behaviour mentioned by the man page is when attempting to detach an already detached thread, which this isn't.
I'm using glibc version 2.39-4.2; could this be a bug?
Update: I've found the code responsible for this, here: https://elixir.bootlin.com/glibc/glibc-2.39/source/nptl/pthread_detach.c#L29
So it seems that "thread ID" in the man page refers to some property (tid, see here) of the thread structure (which is pointed to by the pthread_t
type. This explains the segfault, but I'm still not convinced this is expected behaviour.
Update 2: I just came across this very related question, which seems to pretty much answer this one.
Answers
It appears that you've encountered unexpected behavior when using pthread_detach
with an invalid thread ID. While the behavior you observed may seem surprising, it's not necessarily a bug in glibc; rather, it's a consequence of how pthread_detach
is implemented.
When you pass an invalid thread ID (in this case, 0
) to pthread_detach
, the function tries to access the thread structure associated with that ID. However, since 0
is not a valid thread ID, this results in a segmentation fault.
The behavior you expected, where pthread_detach
returns ESRCH
(indicating that no thread with the specified ID was found), is not mandated by the POSIX standard. Instead, POSIX specifies that passing an invalid thread ID to pthread_detach
results in undefined behavior. This means that the behavior can vary between different implementations of the POSIX threading API, and it's not guaranteed to be consistent or predictable.
In practice, it's generally a good idea to ensure that you're passing valid thread IDs to pthread_detach
to avoid encountering undefined behavior. If you're unsure whether a thread ID is valid, you can use pthread_equal
to compare it against the result of pthread_self
to check if it corresponds to the current thread.