On Sat, Nov 7, 2026 at 11:15 AM Andrea Pinski <[email protected]> wrote: > > On Sat, Nov 7, 2026 at 5:41 AM Rich Felker via Gcc-bugs > <[email protected]> wrote: > > > > On Sat, Nov 07, 2026 at 01:09:03PM +0100, Pepper Gray wrote: > > > According to POSIX, self-joining a thread is undefined behavior: > > > > > > > The behavior is undefined if the value specified by the thread argument > > > > to > > > > pthread_join() refers to the calling thread. > > > > > > ```C > > > #include <pthread.h> > > > #include <stdio.h> > > > #include <string.h> > > > > > > int main(void) { > > > int err = pthread_join(pthread_self(), NULL); // glibc: EDEADLK, > > > musl: never returns > > > printf("returned: %s\n", strerror(err)); > > > } > > > ``` > > > > > > but the rationale recommends detecting it: > > > > > > > If an implementation detects that the value specified by the thread > > > > argument > > > > to pthread_join() refers to the calling thread, it is recommended that > > > > the > > > > function should fail and report an [EDEADLK] error. > > > > > > This is the case in `glibc`, which reports `EDEADLK` while musl just > > > hangs. > > > > > > While hanging is technically correct, the behavior is undesirable in > > > practice, > > > and a behavior like returning `EDEADLK` or even crashing would make it > > > easier to > > > deal with such an app than when it just hangs. > > > > It's very intentional that we do not facilitate forward progress when > > a program has invoked undefined behavior. There is no good reason to > > expect that a programmer has ignored the fact that the operation is UB > > will have taken the effort to check the return value, so just > > returning an error is likely to result in the flow of execution > > continuing to run in an inconsistent and possibly dangerous state. > > > > Self-join suggests a confusion about who owns resources, so this may > > involve data races, etc. But this is a pretty broad principle in musl, > > not specific to pthread_join. At one point my write-up of the > > principle was included in some glibc guidelines too; I can't find the > > link to that at the moment, but FWIW there was consensus that "return > > an error on UB" is bad behavior. > > > > > In C++ this case is defined for `std::thread::join()` > > > ([thread.thread.member](https://eel.is/c++draft/thread.thread.member)): > > > > > > > *Throws:* `system_error` when an exception is required > > > > ([thread.req.exception]). > > > > > > > > *Error conditions:* > > > > - `resource_deadlock_would_occur` — if deadlock is detected or > > > > `get_id() == this_thread::get_id()`. > > > > > > However this doesn't work on `libstdc++` nor `libc++` because they both > > > wrap > > > `pthread_join`, which just hangs on musl. > > > > If the C++ std::thread::join has a contract to throw on self-join then > > it needs to call pthread_equal before pthread_join to check that > > condition. > > libstdc++ works correctly: > ``` > void > thread::join() > { > int __e = EINVAL; > > if (_M_id != id()) //<< check here
Oh wait that is just checking if the id is invalid or not. Let me file a bug. > __e = __gthread_join(_M_id._M_thread, 0); > > if (__e) > __throw_system_error(__e); > > _M_id = id(); > } > ```
