mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: Арсений <a@saur0n.science>
Cc: musl@lists.openwall.com
Subject: Re: [musl] Mutexes are not unlocking
Date: Sun, 22 Nov 2020 14:11:07 -0500	[thread overview]
Message-ID: <20201122191106.GO534@brightrain.aerifal.cx> (raw)
In-Reply-To: <1606070615.957905591@f395.i.mail.ru>

On Sun, Nov 22, 2020 at 09:43:35PM +0300, Арсений wrote:
> 
> Hello,
> The problem is that mutex is not got unlocked after the first unlock().
>  
> libstdc++ uses a wrapper for pthread called gthreads. This wrapper
> checks for the state of the mutex system. For
> example, pthread_mutex_unlock() is called in a following way:
>  
> static inline int
> __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
> {
>   if (__gthread_active_p ())
>     return __gthrw_(pthread_mutex_unlock) (__mutex);
>   else
>     return 0;
> }

Yes. This code is invalid (it misinterprets weak symbol information to
draw incorrect conclusions about whether threads may be in use) and
thus is disabled in builds of gcc/libstdc++ targeting musl-based
systems. GCC and glibc-based distro folks mostly don't care because
it only breaks static linking, but some of them actually hack gcc's
libpthread.a into one giant .o file to work around the problem rather
than fixing this in gcc...

> The function __gthread_active_p() is an inline function which
> returns non-nullptr value is pthreads is available.
> 
> It seems that std::mutex::lock() in libstdc++ from Alpine Linux
> repos does not use ghtreads:

Yes. That's a standard requirement for building a musl-targeting gcc.

>  
> => 0x00007ffff7eb6dde <+0>:     push   %rdx
>    0x00007ffff7eb6ddf <+1>:     callq  0x7ffff7eaf550 <pthread_mutex_lock@plt>
>    0x00007ffff7eb6de4 <+6>:     test   %eax,%eax
>    0x00007ffff7eb6de6 <+8>:     je     0x7ffff7eb6def <_ZNSt5mutex4lockEv+17>
>    0x00007ffff7eb6de8 <+10>:    mov    %eax,%edi
>    0x00007ffff7eb6dea <+12>:    callq  0x7ffff7eb3f50 <_ZSt20__throw_system_errori@plt>
>    0x00007ffff7eb6def <+17>:    pop    %rax
>    0x00007ffff7eb6df0 <+18>:    retq 
>  
> std::mutex::lock() from glibc-compatible libstdc++ is not inlined by
> compiler during build, because it contains check for errors:
>     void
>     lock()
>     {
>       int __e = __gthread_mutex_lock(&_M_mutex);
> 
>       // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
>       if (__e)
>     __throw_system_error(__e);
>     }
>  
> std::mutex::unlock() from glibc-compatible libstdc++ is inlined,
> because it does not contain anything but call to
> __gthread_mutex_lock():
>     void
>     unlock()
>     {
>       // XXX EINVAL, EAGAIN, EPERM
>       __gthread_mutex_unlock(&_M_mutex);
>     }
> This is why pthread_mutex_lock() from musl is called, but pthread_mutex_unlock() is not.

Thanks for doing the root cause analysis here. It will be interesting
(and probably infuriating) to the gcompat folks working on making
glibc-linked binaries work on musl, but maybe they already have a
workaround for this.

Anyway the answer to your original question is probably just "don't do
that" unless you want to get into fixing GCC...

Rich

  reply	other threads:[~2020-11-22 19:11 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20  5:25 a
2020-11-20  5:58 ` Rich Felker
2020-11-21  6:46   ` Re[2]: " a
2020-11-21 15:51     ` Rich Felker
2020-11-22 18:43       ` Re[2]: " Арсений
2020-11-22 19:11         ` Rich Felker [this message]
2020-11-22 19:23           ` Florian Weimer
2020-11-22 19:28             ` Rich Felker
2020-11-22 19:45               ` Re[2]: " Арсений
2020-11-22 20:05               ` Арсений
2020-11-23 12:24                 ` Jonathan Wakely
2020-11-23 14:56                   ` Rich Felker
2020-11-23 16:58                     ` Jonathan Wakely
2020-11-23 11:41               ` Jonathan Wakely
2020-11-23 14:53                 ` Rich Felker
2020-11-23 16:19                   ` Jonathan Wakely
2020-11-23 16:51                     ` Rich Felker
2020-11-23 17:10                       ` Jonathan Wakely
2020-11-23 17:18                         ` Florian Weimer
2020-11-23 16:59                     ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201122191106.GO534@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=a@saur0n.science \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).