Crash. Is it GMock bug or mine?

2,377 views
Skip to first unread message

Vladimir Florentino

unread,
Jun 23, 2009, 10:02:10 AM6/23/09
to Google C++ Mocking Framework
I have a code like this:

class Engine
{
public:
Engine(){mockSetup();}

void Report(const char* text, unsigned long flags = 0) {};
//MOCK_METHOD2(Report, void(const char* text, unsigned long flags));
//void Report(const char* text) { Report(text, 0);} // Not in
original -- to deal with default argument.

//void InstallMouseEventHandler(MouseEventHandler*) {};
MOCK_METHOD1(InstallMouseEventHandler, void(MouseEventHandler*));

private:
void mockSetup()
{
/*
EXPECT_CALL(*this, Report(_, _))
.Times(AnyNumber());
*/
EXPECT_CALL(*this, InstallMouseEventHandler(_))
.Times(AnyNumber());

}
};






If i comment out this mock definition:
MOCK_METHOD1(InstallMouseEventHandler, void(MouseEventHandler*));

and have the normal method, the tests run fine.

Any mock definition in that class seems to crash the test.

That engine object is basically a singleton with a global pointer,
created in it's .cpp file.

I have other mocked objects which run fine. However, from the other
tests, none of those objects are global.

The crash happens at the xtree file, from the std lib.

This code talks to a DLL.

Can't think of any other relevant info.

Here's the stack trace of the crash:

> Test.exe!std::_Tree<std::_Tmap_traits<void const *,testing::`anonymous namespace'::MockObjectState,std::less<void const *>,std::allocator<std::pair<void const * const,testing::`anonymous namespace'::MockObjectState> >,0> >::_Lbound(const void * const & _Keyval=0x00404ea8) Line 1264 + 0x8 bytes

Test.exe!std::_Tree<std::_Tmap_traits<void const
*,testing::`anonymous namespace'::MockObjectState,std::less<void const
*>,std::allocator<std::pair<void const * const,testing::`anonymous
namespace'::MockObjectState> >,0> >::lower_bound(const void * const &
_Keyval=0x00404ea8) Line 1004 + 0x10 bytes

Test.exe!std::map<void const *,testing::`anonymous
namespace'::MockObjectState,std::less<void const
*>,std::allocator<std::pair<void const * const,testing::`anonymous
namespace'::MockObjectState> > >::operator[](const void * const &
_Keyval=0x00404ea8) Line 169 + 0x10 bytes

Test.exe!testing::Mock::Register(const void * mock_obj=0x00404ea8,
testing::internal::UntypedFunctionMockerBase * mocker=0x00404ea8)
Line 353 + 0x1d bytes

Test.exe!testing::internal::FunctionMockerBase<void __cdecl
(C4::MouseEventHandler *)>::RegisterOwner(const void *
mock_obj=0x00404ea8) Line 1171 + 0xd bytes

Test.exe!C4X::Engine::gmock_InstallMouseEventHandler(const
testing::Matcher<C4::MouseEventHandler *> & gmock_a1={...}) Line 198
+ 0x33 bytes

Test.exe!C4X::Engine::mockSetup() Line 208 + 0x67 bytes

Test.exe!C4X::Engine::Engine() Line 191 + 0x59 bytes

Test.exe!C4X::`dynamic initializer for 'TheEngine''() Line 7 + 0x68
bytes

Test.exe!_initterm(void (void)* * pfbegin=0x011807d4, void (void)* *
pfend=0x01180bbc) Line 903

Test.exe!_cinit(int initFloatingPrecision=1) Line 307 + 0xf bytes

Test.exe!__tmainCRTStartup() Line 249 + 0x7 bytes

Test.exe!mainCRTStartup() Line 182

JJ

unread,
Jun 23, 2009, 10:28:14 AM6/23/09
to Google C++ Mocking Framework
You have, I would guess, run into the Static Initialization Order
Fiasco, as detailed in the C++ FAQ Lite at
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12. Somewhere
in the internals of the implementation of gmock there are presumably
some static registries of mock objects (or equivalent), which are, due
to an essentially random decision of your compiler, not being
initialized before your own static object is. Therefore, your implicit
attempt to access them caused by your call to EXPECT_CALL is crashing.

A sensible way to get around this, assuming it is the problem, is to
use the Construct On First Use idiom, instead of directly creating a
global object. It's not worth my detailing that in full here, because
it's also described in the C++ FAQ Lite immediately below the previous
link.

Of course, if this is the problem, then maybe the implementation of
gmock should be doing the same thing...

Hope this helps,

JJ

vlad

unread,
Jun 23, 2009, 11:46:07 AM6/23/09
to Google C++ Mocking Framework
I did a test and seems to be that.

Thanks, JJ.

Zhanyong Wan (λx.x x)

unread,
Jun 23, 2009, 12:58:46 PM6/23/09
to JJ, Google C++ Mocking Framework

You are right. We used a global object for the registry for
simplicity and can instead create it on demand. This wasn't a high
priority as it's good style to have each test create and destroy its
own mocks (less dependencies between tests).

http://code.google.com/p/googlemock/issues/detail?id=54 tracks this.

--
Zhanyong

Reply all
Reply to author
Forward
0 new messages