|
|
Message-ID: <CALvbMcB5Mw+Edn_ZdCoHYu-esRAQhPdd8hPxZSizjGmKX2Hb0A@mail.gmail.com>
Date: Sat, 7 Nov 2026 11:22:58 -0800
From: Andrea Pinski <andrew.pinski@....qualcomm.com>
To: Rich Felker <dalias@...c.org>
Cc: Pepper Gray <hello@...pergray.xyz>, llvm-bugs@...ts.llvm.org,
gcc-bugs@....gnu.org, musl@...ts.openwall.com
Subject: Re: pthread self join hangs on musl
On Sat, Nov 7, 2026 at 11:15 AM Andrea Pinski
<andrew.pinski@....qualcomm.com> wrote:
>
> On Sat, Nov 7, 2026 at 5:41 AM Rich Felker via Gcc-bugs
> <gcc-bugs@....gnu.org> 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();
> }
> ```
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.