|
From: André O. <off...@gm...> - 2019-03-11 21:57:30
|
Hi all,
I'm struggling with a helgrind error that I don't understand. I've
stripped the code to a minimal example that shows the issue and pasted
the code below. As far as I can tell, the code should be thread safe,
and I've looked at the gcc assembly output, and I can't see anything
wrong with it so, so far I don't suspect it is a gcc error (but I'm not
certain).
The helgrind error only appears when I compile with -O0, -O1 or -O2, not
with -O3. Also, when I call "get_int_no_warning" instead of "get_int",
no helgrind errors are reported.
Would anybody be able to tell me if this is a helgrind false positive?
I compile with gcc (Debian 8.3.0-2) 8.3.0 and am using valgrind-3.14.0
from Debian testing.
(the weird method is used in a codebase to create an instance of an
object that is never destructed but isn't reported as leaked memory
either -- it's a hack around some static initialization order problems).
Source code:
#include <new>
#include <iostream>
#include <vector>
#include <thread>
#include <memory>
int* get_int()
{
static std::aligned_storage_t<sizeof(int), alignof(int)> storage;
// The following line is pointed out in a helgrind warning:
// "Possible data race during read of size 8..."
// When using -O2, this conflicts with a previous write of size 8,
also at this line...
static int* ptr = new (reinterpret_cast<int*>(&storage)) int();
return ptr; // But with -O0, the previous line conflicts with this
return statement.
}
int* get_int_no_warning()
{
static int x = 0;
return &x;
}
void test()
{
volatile int* a = get_int();
}
int main()
{
std::thread a(test), b(test);
a.join();
b.join();
}
Thanks,
André
|
|
From: Patrick J. L. <lop...@gm...> - 2019-03-11 22:17:38
|
I believe Helgrind does not understand modern GCC implementations of the Meyers Singleton. You will see similar warnings for any non-trivial static object. See e.g. https://stackoverflow.com/q/44698412/ I vaguely recall this was discussed here before and deemed "hard to fix". But I cannot seem to find that discussion. - Pat On Mon, Mar 11, 2019 at 2:59 PM André Offringa <off...@gm...> wrote: > Hi all, > > I'm struggling with a helgrind error that I don't understand. I've > stripped the code to a minimal example that shows the issue and pasted > the code below. As far as I can tell, the code should be thread safe, > and I've looked at the gcc assembly output, and I can't see anything > wrong with it so, so far I don't suspect it is a gcc error (but I'm not > certain). > > The helgrind error only appears when I compile with -O0, -O1 or -O2, not > with -O3. Also, when I call "get_int_no_warning" instead of "get_int", > no helgrind errors are reported. > > Would anybody be able to tell me if this is a helgrind false positive? > > I compile with gcc (Debian 8.3.0-2) 8.3.0 and am using valgrind-3.14.0 > from Debian testing. > > (the weird method is used in a codebase to create an instance of an > object that is never destructed but isn't reported as leaked memory > either -- it's a hack around some static initialization order problems). > > Source code: > > #include <new> > #include <iostream> > #include <vector> > #include <thread> > #include <memory> > > int* get_int() > { > static std::aligned_storage_t<sizeof(int), alignof(int)> storage; > > // The following line is pointed out in a helgrind warning: > // "Possible data race during read of size 8..." > // When using -O2, this conflicts with a previous write of size 8, > also at this line... > static int* ptr = new (reinterpret_cast<int*>(&storage)) int(); > > return ptr; // But with -O0, the previous line conflicts with this > return statement. > } > > int* get_int_no_warning() > { > static int x = 0; > return &x; > } > > void test() > { > volatile int* a = get_int(); > } > > int main() > { > std::thread a(test), b(test); > a.join(); > b.join(); > } > > Thanks, > André > > > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > |