Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1606070615.957905591@f395.i.mail.ru>
Date: Sun, 22 Nov 2020 21:43:35 +0300
From: Арсений <a@...r0n.science>
To: Rich Felker <dalias@...c.org>
Cc: musl@...ts.openwall.com
Subject: Re[2]: Mutexes are not unlocking


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;
}
 
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:
 
=> 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.
  
>Суббота, 21 ноября 2020, 18:51 +03:00 от Rich Felker <dalias@...c.org>:
> 
>On Sat, Nov 21, 2020 at 09:46:57AM +0300,  a@...r0n.science wrote:
>> Hello,
>> Thanks for the fast response.
>>
>> I compiled binary under OpenSUSE towards glibc and started on Alpine
>> Linux.
>
>I think you mean just compiled normally on OpenSUSE without doing
>anything related to musl at this point, but could you please conform
>that that's the case?
>
>Also, did you link libstdc++ statically or dynamically? Are you moving
>any additional shared libraries over from the glibc system, or just
>the application binary? Does it have any other libraries static linked
>into it?
>
>This is why I asked for full information on how you built it. The
>answers to these questions determine what direction you should look
>in.
>
>musl provides some minimal level of glibc-ABI-compat for attempting to
>get binaryware that you can't rebuild against musl to work. This
>doesn't mean building binaries for glibc and attempting to use them
>with musl is necessarily supported usage. It's possible that you're
>doing something that just can't work, but it's also possible that
>there are simple mistakes you could correct and get this working.
>
>> I think it is not a problem because mutex is aggregated by a
>> pointer.
>
>I'm also not clear exactly what you mean by that.
>
>> I am using gcc 10.2.1 20201028 [revision
>> a78cd759754c92cecbf235ac9b447dcdff6c6e2f] installed from OpenSUSE
>> reporitories.
>>
>> Unfortunately, I cannot post a "minimal working example", because
>> the bug does not reproduce on a small programs.
>
>This means the problem is in something you haven't shown or described.
>
>> This is the internal state of the mutex which caused problems at the
>> moment of second lock operation:
>
>> (gdb) print gsMutex
>> $1 = {<std::__mutex_base> = {_M_mutex = {__data = {__lock = 0, __count = 2147483664, __owner = 1, __nusers = 0, __kind = 0, __spins = 0, __elision = 0, __list = {
>>          __prev = 0x0 , __next = 0x0 }}, __size = "\000\000\000\000\020\000\000\200\001", '\000' <repeats 30 times>, __align = -9223371968135299072}}, <No data fields>}
>
>This is printing out a glibc data structure, which isn't going to be
>meaningful.
>
>Rich
 
 
——
Арсений
 
Content of type "text/html" skipped

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.