Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tsan] Is this false warning when using std::condition_variable like this? #1683

Open
Rereflyer opened this issue Sep 11, 2023 · 1 comment

Comments

@Rereflyer
Copy link

Rereflyer commented Sep 11, 2023

When compiling the following code with gcc7, utilizing thread sanitizer

#include <pthread.h>
#include <stdio.h>

int Global = 0x12345678;
pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;

void *Thread1(void *x) {
    pthread_mutex_lock(&mu);
    pthread_cond_wait(&condition, &mu);
    printf("print Global:0x%X\n",Global);
    return x;
}

void *Thread2(void *x) {
    char* c1 = (char*)(&Global) + 3;
    (*c1) = 1;
    pthread_cond_signal(&condition);
    return x;
}

int main() {
    pthread_t t1;
    pthread_t t2;
    pthread_create(&t1, NULL, Thread1, NULL);
    pthread_create(&t2, NULL, Thread2, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    return Global;
}

Generated warnings when running the program:

==================
WARNING: ThreadSanitizer: data race (pid=126626)
  Read of size 4 at 0x55de3589e010 by thread T1 (mutexes: write M0):
    #0 Thread1 /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:11 (sim_oneDNN_wait.out+0x125d)
    #1 <null> <null> (libtsan.so.0+0x296ad)

  Previous write of size 1 at 0x55de3589e013 by thread T2:
    #0 Thread2 /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:17 (sim_oneDNN_wait.out+0x12b9)
    #1 <null> <null> (libtsan.so.0+0x296ad)

  Location is global 'Global' of size 4 at 0x55de3589e010 (sim_oneDNN_wait.out+0x000000004010)

  Mutex M0 (0x55de3589e080) created at:
    #0 pthread_mutex_lock <null> (libtsan.so.0+0x3fadb)
    #1 Thread1 /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:9 (sim_oneDNN_wait.out+0x123e)
    #2 <null> <null> (libtsan.so.0+0x296ad)

  Thread T1 (tid=126628, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x2bcee)
    #1 main /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:25 (sim_oneDNN_wait.out+0x1320)

  Thread T2 (tid=126629, finished) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x2bcee)
    #1 main /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:26 (sim_oneDNN_wait.out+0x133d)

SUMMARY: ThreadSanitizer: data race /home/xx/work/verify/c++/tsan/sim_oneDNN_wait.c:11 in Thread1
==================
print Global:0x1345678
ThreadSanitizer: reported 1 warnings

I am building the code with the following command:
gcc sim_wait.c -o sim_wait.out -fsanitize=thread -g

In my opinion, Thread1 will wait condition variale so write global variable must happen before read global variable, is this false warning when tsan report data race? Thanks.

@tavianator
Copy link

pthread_cond_wait() is allowed to return spuriously:

When using condition variables there is always a Boolean predicate involving shared variables associated with each condition wait that is true if the thread should proceed. Spurious wakeups from the pthread_cond_timedwait() or pthread_cond_wait() functions may occur. Since the return from pthread_cond_timedwait() or pthread_cond_wait() does not imply anything about the value of this predicate, the predicate should be re-evaluated upon such return.

https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants