I've always thought that using std::cout << something
was thread safe.
For this little example
#include <iostream>
#include <thread>
void f()
{
std::cout << "Hello from f\n";
}
void g()
{
std::cout << "Hello from g\n";
}
int main()
{
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
}
my expectation was that the order of the two outputs would be undefined (and indeed that is what I observe in practice), but that the calls to operator<<
are thread safe.
However, ThreadSanitizer, DRD and Helgrind all seem to give various errors regarding access to std::__1::ios_base::width(long) and std::__1::basic_ios<char, std::__1::char_traits >::fill()
On Compiler Explorer I don't see any errors.
On FreeBSD 13, ThreadSanitizer gives me 3 warnings, the two listed above plus the malloc/memcpy to the underlying i/o buffer.
Again in FreeBSD 13, DRD gives 4 errors, width()
and fill()
times two for the two threads.
Finally FreeBSD 13 Helgrind gives one known false positive related to TLS in thread creation, fill()
and ẁidth()` twice.
On Fedora 34
- No errors with g++ 11.2.1 and ThreadSanitizer
- DRD complains about malloc/memcpy in fwrite with g++ compiled exe
- Helgrind also complains about fwrite and also for the construction of
cout
, again with the g++ compiled exe - clang++ 12 ThreadSanitizer complains about
fill()
andwidth()
- DRD with the clang++ compiler exe complains about
fill()
,width()
,fwrite
and one other instart_thread
- Helgrind with the clang++ exe complains about some TLS,
fill()
,width()
,fwrite
Looking at the libc++ and libstdc++ code I don't see anything at all that protects width()
. So I don't understand why there are no complaints on compiler explorer.
Is there a way with tsan to either see the suppresions that are being used or to ignore default suppressions (assuming that there are some default suppressions)?
Aucun commentaire:
Enregistrer un commentaire