public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* Could you kindly explain this modification about pthread_cond_destroy?
@ 2017-11-27  7:53 honan li
  2017-11-27 12:03 ` Florian Weimer
  0 siblings, 1 reply; 3+ messages in thread
From: honan li @ 2017-11-27  7:53 UTC (permalink / raw)
  To: libc-help

We came across a Linux app issue that while invoke
pthread_cond_destroy, it is pending there forever. After investigation
we find that is because a waiter is being blocked (by
pthread_cond_wait) while doing pthread_cond_destroy.

This issue didn't occur on our previous platform using
glibc2.20(Yocto1.7), while it always occurs after we upgraded to
Yocto2.2(includs glibc after version 2.24). We checked glibc history
and find issue seems related to commit ed19993b5 by Torvald Riegel on
31 Dec 2016.

We do noticed the comment of __pthread_cond_destroy, it mentioned "A
correct program must make sure that no waiters are blocked on the
condvar when it is destroyed.", "It must also ensure that no signal or
broadcast are still pending to unblock waiters." and "destruction that
is concurrent with still-active waiters is probably neither common nor
performance critical.".
But back to our issue, on the Qualcomm platform we are working on,
there are many places invoking pthread_cond_destroy, but after each
pthread_cond_destroy, thread or even the process would exit, and at
least for now it seems working all right on glibc2.20. Could you
kindly explain what is the potential risk of the case?

//below is the simple app to verify the issue. App always got stuck on
pthread_cond_destroy on glibc2.25, while on glibc2.20 it ends well.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *thread1(void *);
void *thread2(void *);
int main(void)
{
     pthread_t t_a;
     pthread_t t_b;
     pthread_create(&t_a,NULL,thread1,(void *)NULL);
     pthread_create(&t_b,NULL,thread2,(void *)NULL);
     sleep(1);

     pthread_cond_destroy(&cond);
     pthread_mutex_destroy(&mutex);
     exit(0);
}
void *thread1(void *args)
{
    pthread_cond_wait(&cond,&mutex);
}
void *thread2(void *args)
{
}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Could you kindly explain this modification about pthread_cond_destroy?
  2017-11-27  7:53 Could you kindly explain this modification about pthread_cond_destroy? honan li
@ 2017-11-27 12:03 ` Florian Weimer
  2017-11-27 12:15   ` Adhemerval Zanella
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Weimer @ 2017-11-27 12:03 UTC (permalink / raw)
  To: honan li; +Cc: libc-help

On 11/27/2017 08:52 AM, honan li wrote:
> But back to our issue, on the Qualcomm platform we are working on,
> there are many places invoking pthread_cond_destroy, but after each
> pthread_cond_destroy, thread or even the process would exit, and at
> least for now it seems working all right on glibc2.20. Could you
> kindly explain what is the potential risk of the case?

I'm not sure if I understand this question.

It results in undefined behavior.  Your application could crash, hang, 
or even exhibit silent memory corruption, resulting in incorrect results.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Could you kindly explain this modification about pthread_cond_destroy?
  2017-11-27 12:03 ` Florian Weimer
@ 2017-11-27 12:15   ` Adhemerval Zanella
  0 siblings, 0 replies; 3+ messages in thread
From: Adhemerval Zanella @ 2017-11-27 12:15 UTC (permalink / raw)
  To: libc-help



On 27/11/2017 10:03, Florian Weimer wrote:
> On 11/27/2017 08:52 AM, honan li wrote:
>> But back to our issue, on the Qualcomm platform we are working on,
>> there are many places invoking pthread_cond_destroy, but after each
>> pthread_cond_destroy, thread or even the process would exit, and at
>> least for now it seems working all right on glibc2.20. Could you
>> kindly explain what is the potential risk of the case?
> 
> I'm not sure if I understand this question.
> 
> It results in undefined behavior.  Your application could crash, hang, or even exhibit silent memory corruption, resulting in incorrect results.
> 
> Thanks,
> Florian

As Florian pointed out and in your example pthread_cond_destroy is racing 
with pthread_cond_wait and you can check it with TSAN.  You should not 
rely on undefined behaviour.

$ gcc -Wall test-cond.c -o test-cond -pthread -fsanitize=thread
$ ./test-cond 
==================
WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread) (pid=30973)
    #0 pthread_cond_wait <null> (libtsan.so.0+0x0000000279de)
    #1 thread1 <null> (test-cond+0x0000004009ed)
    #2 <null> <null> (libtsan.so.0+0x0000000230d9)

  Location is global 'mutex' of size 40 at 0x0000004020a0 (test-cond+0x0000004020a0)

  Mutex M0 (0x0000004020a0) created at:
    #0 pthread_cond_wait <null> (libtsan.so.0+0x0000000279de)
    #1 thread1 <null> (test-cond+0x0000004009ed)
    #2 <null> <null> (libtsan.so.0+0x0000000230d9)

SUMMARY: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread) ??:0 __interceptor_pthread_cond_wait
==================
==================
WARNING: ThreadSanitizer: data race (pid=30973)
  Write of size 8 at 0x0000004020e0 by main thread:
    #0 pthread_cond_destroy <null> (libtsan.so.0+0x000000027f97)
    #1 main <null> (test-cond+0x0000004009b2)

  Previous read of size 8 at 0x0000004020e0 by thread T1:
    #0 pthread_cond_wait <null> (libtsan.so.0+0x0000000279de)
    #1 thread1 <null> (test-cond+0x0000004009ed)
    #2 <null> <null> (libtsan.so.0+0x0000000230d9)

  As if synchronized via sleep:
    #0 sleep <null> (libtsan.so.0+0x000000043956)
    #1 main <null> (test-cond+0x0000004009a8)

  Location is global 'cond' of size 48 at 0x0000004020e0 (test-cond+0x0000004020e0)

  Thread T1 (tid=30975, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 main <null> (test-cond+0x000000400983)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_pthread_cond_destroy
==================
==================
WARNING: ThreadSanitizer: thread leak (pid=30973)
  Thread T2 (tid=30976, finished) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 main <null> (test-cond+0x00000040099e)

SUMMARY: ThreadSanitizer: thread leak ??:0 __interceptor_pthread_create
==================
ThreadSanitizer: reported 3 warnings

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-11-27 12:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-27  7:53 Could you kindly explain this modification about pthread_cond_destroy? honan li
2017-11-27 12:03 ` Florian Weimer
2017-11-27 12:15   ` Adhemerval Zanella

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 read-only IMAP folder(s) and NNTP newsgroup(s).