|
From: David F. <fa...@kd...> - 2016-03-30 08:59:55
|
This simple testcase :
int foo() {
struct Foo {
int *i;
Foo() { i = new int(42); }
};
static Foo f;
return *(f.i);
}
called from two threads (http://www.davidfaure.fr/2016/testcase_ogoffart.cpp)
leads to this race warning in helgrind :
==16440== Possible data race during read of size 8 at 0x602070 by thread #3
==16440== Locks held: none
==16440== at 0x400B34: foo() (testcase_ogoffart.cpp:10)
==16440== by 0x400B48: threadStart(void*) (testcase_ogoffart.cpp:16)
==16440== by 0x4C3005E: mythread_wrapper (hg_intercepts.c:389)
==16440== by 0x4E430A3: start_thread (pthread_create.c:309)
==16440== by 0x595D00C: clone (clone.S:111)
==16440==
==16440== This conflicts with a previous write of size 8 by thread #2
==16440== Locks held: none
==16440== at 0x400AF2: foo()::Foo::Foo() (testcase_ogoffart.cpp:7)
==16440== by 0x400B1B: foo() (testcase_ogoffart.cpp:9)
==16440== by 0x400B48: threadStart(void*) (testcase_ogoffart.cpp:16)
==16440== by 0x4C3005E: mythread_wrapper (hg_intercepts.c:389)
==16440== by 0x4E430A3: start_thread (pthread_create.c:309)
==16440== by 0x595D00C: clone (clone.S:111)
==16440== Address 0x602070 is 0 bytes inside data symbol "_ZZ3foovE1f"
with both clang and gcc.
(and without -Wno-threadsafe-statics)
I assume that both compilers are not buggy. More likely, helgrind doesn't recognize
the atomic operations used by the compilers to protect the initialization of Foo ?
<bb 3>:
_5 = __cxa_guard_acquire (&_ZGVZ3foovE1f);
if (_5 != 0)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
foo()::Foo::Foo (&f);
__cxa_guard_release (&_ZGVZ3foovE1f);
Isn't cxa_guard_acquire implemented with mutexes? (Google seems to say so)
Why then does helgrind see a race? It doesn't catch the mutexes used internally in libstdc++?
--
David Faure, fa...@kd..., http://www.davidfaure.fr
Working on KDE Frameworks 5
|