Application crashed due to no guarantee of the initialization order of global instances between gmock and programm
Opened this issue · 3 comments
GoogleCodeExporter commented
This phenomenon can appear repeatedly if our program is linked with gmock/gtest
object files. However the crash is gone if we link our program with gmock/gtest
static libraries.
Steps:
1. Compile all the source codes including gmock/gtest source.
2. link all the object files as a single executable.
3. Run this program with options --gtest_output --gtest_filter
We check the coredump file and find the program crashed just before the main
function with signal segment fault - invalid access to
g_uninteresting_call_reaction. This variable is defined in gmock as a global
variable.
Here I summary why this happens:
Our program defines some global variables such as: NiceMock<Something>
something.
The template class NiceMock's constructor accesses the global variable
g_uninteresting_call_reaction. These 2 variables locate in different
translation units and the compiler has no guarantee of the initialization order
of global instances between different translation units.
Could you please provide solution for this? For example, add #pragma init_seg
preprocessor directive for some global variables?
Platform: Linux 2.6.32-358.23.2.el6.x86_64 #1 SMP Wed Oct 16 18:37:12 UTC 2013
x86_64 x86_64 x86_64 GNU/Linux
gmock/gtest: 1.7.0
compiler: GNU g++ 4.7.4
Original issue reported on code.google.com by threepea...@gmail.com
on 23 May 2014 at 8:52
GoogleCodeExporter commented
I can reproduce the same issue with compiler GNU g++ 4.7.3:
Here's code that can reproduce the issue:
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using testing::NiceMock;
class Foo {
public:
virtual ~Foo() {}
virtual void DoThis() = 0;
virtual int DoThat(bool flag) = 0;
};
class FooMock : public Foo {
public:
FooMock() {}
MOCK_METHOD0(DoThis, void());
MOCK_METHOD1(DoThat, int(bool flag));
};
// If uncommented, g++ 4.6.3+ will crash before main() is called
// NiceMock<FooMock> *g_mockFoo = new NiceMock<FooMock>;
// If uncommected, g++ 4.6.3+ will crash before main() is called
// NiceMock<FooMock> g_mockFoo2;
TEST(NiceMockTest, ThisTestPasses)
{
NiceMock<FooMock> mockFoo; // Does not cause crash
mockFoo.DoThis();
mockFoo.DoThat(true);
}
Original comment by Gramanda...@gmail.com
on 5 Sep 2014 at 2:12
GoogleCodeExporter commented
I should elaborate why this is important to me... If I have a "C" interface
that I want to mock, to translate between c and c++ gmock library, I do this:
myfile.c
--------
void add1() { Best_Add1(); }
void sub1() { Best_Sub1(); }
myMock.cpp
----------
class MockBest {
public:
MOCK_METHOD0(Add1, void());
MOCK_METHOD0(Sub1, void());
};
NiceMock<MockBest> bestMock;
extern "C" {
Better_Add1(){
bestMock.Add1();
}
Better_Sub1(){
bestMock.Sub1();
}
};
Without NiceMock, this design works perfectly well, however, when adding in
NiceMock, I get the above crash which is preventing me from testing "C"
interfaces with GoogleMock library (unless I want to see thousands of warnings)
;-). Please help evaluate a workaround, and possibly increase the priority of
this fix.
Original comment by Gramanda...@gmail.com
on 5 Sep 2014 at 2:25
GoogleCodeExporter commented
I'll try making the g_uninteresting_call_reaction map a lazily-initialized
object accessible only through an accessor function. But I really think you
should do the same with your bestMock. Then you probably wouldn't have this
problem.
class MockBest {
public:
MOCK_METHOD0(Add1, void());
MOCK_METHOD0(Sub1, void());
};
MockBest& GetMockBest() {
static NiceMock<MockBest> v = NiceMock<MockBest>();
return v;
}
extern "C" {
Better_Add1(){
GetMockBest().Add1();
}
Better_Sub1(){
GetMockBest().Sub1();
}
};
Original comment by billydon...@google.com
on 6 Sep 2014 at 6:30