I wrote the following toy example:
std::map getMap(const std::string& s)
{
std::map map;
size_t i = 0;
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