GCC's TSAN reports a data race with a thread safe static local

前端 未结 1 1624
后悔当初
后悔当初 2021-01-05 08:48

I wrote the following toy example:

std::map getMap(const std::string& s)
{
    std::map map;
    size_t i = 0;
           


        
相关标签:
1条回答
  • 2021-01-05 09:29

    is TSan buggy ? (When I am using Clang's toolchain, I get no data race report) does GCC emit code which is not thread safe? (I am not using -fno-threadsafe->statics though) is my understanding of static locals incorrect?

    I believe this is bug in gcc part that generate code for tsan purposes.

    I try this:

    #include <thread>
    #include <iostream>
    #include <string>
    
    std::string message()
    {
        static std::string msg("hi");
        return msg;
    }
    
    int main()
    {
        std::thread t1([]() { std::cout << message() << "\n"; });
        std::thread t2([]() { std::cout << message() << "\n"; });
    
        t1.join();
        t2.join();
    }
    

    If look at code generate by clang and gcc, all good, __cxa_guard_acquire is called in both cases for path that init static local variable. But in case of check that we need init msg or not we have problem.

    The code looks like this

    if (atomic_flag/*uint8_t*/) {
      lock();
      call_constructor_of_msg();
      unlock();
    }
    

    in case of clang callq __tsan_atomic8_load was generated, but in the case of gcc it generate callq __tsan_read1. Note that this calls annotate real memory operations, not do operations by itself.

    so it at runtime tsan runtime library thinks that all bad, and we have data race, I report problem here:

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68338

    and looks like it fixed in trunk, but not in current stable release of gcc - 5.2

    0 讨论(0)
提交回复
热议问题