vinipsmaker
vinipsmaker

Reputation: 2397

Is it reliable to use pthread_self() to get a thread ID even from C++ threads?

On Linux, libstdc++ doesn't use pthread_create() to create threads, as it can be seen from this bug: https://bugzilla.kernel.org/show_bug.cgi?id=218607 (libpsx wraps pthread_create() to intercept thread creation, but that doesn't work on C++ threads which can only mean libstdc++ doesn't use pthread_create()).

I'm not here to report bugs or anything like that, so now that this little bit of context was introduced, let's go to my actual question.

For the architecture of my software, I need a thread ID. The thread might have been created from C libraries or C++ libraries. I don't control that. A function (callback) that I wrote (so some code that I do control) is called from such thread. I need to get a thread ID from this callback.

Requirements for my thread ID:

So my question is: is it reliable to use pthread_self() from C++/libstdc++ threads? In case pthread_self() is not reliable to call from C++ threads, do you suggest an alternative approach for generating a thread ID?

A little bit more of context: I'm creating a capsicum sandbox on FreeBSD (I'm doing something very very similar on Linux with Landlock+seccomp so glibc/libstdc++ problems also matter to me... hence this question), but I wish to reuse existing C/C++ libraries. Capsicum fully disables ambient authority. I'm wrapping libc functions that acquire resources from ambient authority. My libc function overriders send messages over an UNIX unnamed socket to a supervisor that lives outside the sandbox. Given any thread might use these functions, the request includes the thread ID (hence the need to be able to serialize the thread ID in a C struct) and blocks the thread until the matching reply is received.

Upvotes: 0

Views: 111

Answers (1)

John Bollinger
John Bollinger

Reputation: 181199

Is it reliable to use pthread_self() to get a thread ID even from C++ threads?

It depends on what characteristics you want to rely upon. If you're on a POSIX system, then it is safe to call pthread_self(), and it always succeeds. But when such a call occurs in a C++ program, neither POSIX nor C++ defines any relationship between the resulting pthread_t and the properties of the std::thread in whose context the call occurs. Not even that you will get different results from calls in different std::threads.

You might discover such a relationship empirically, but that would not be safe to rely upon. You might find a relationship documented by your C++ implementation, and that would be safe to rely upon in the context of that implementation, but such reliance would constitute a portability issue.

You write:

For the architecture of my software, I need a thread ID. The thread might have been created from C libraries or C++ libraries. I don't control that. A function (callback) that I wrote (so some code that I do control) is called from such thread. I need to get a thread ID from this callback.

The problem there is that "thread" is not well enough defined in those specifications. You need to either know or be told what kind of thread you need an ID for, so that you can use an appropriate mechanism to get an ID. And if you need to accommodate different kinds of threads in the same program then you have extra work to do.

One way forward would be to require pthreads use, including in C++ programs. That's no big deal for a C++ implementation that uses pthreads and maintains a stable 1:1 relationship between std::threads and pthreads. With any other kind of C++ implementation, however, it would likely manifest unwanted behavior in C++ programs that use std::thread.

That nevertheless seems natural to me for a system on which pthreads is considered the one and only native thread library. To the extent that it is sensitive to threading, a container / sandbox such as you describe should be expected to operate in terms of native threads. If that causes issues for applications that use a different threading scheme then you could reasonably (according to me) say that's someone else's problem.

Upvotes: 1

Related Questions