michaelernst / googlemock

Automatically exported from code.google.com/p/googlemock
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Deadlock if an expectation matcher calls another expected call #113

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. EXPECT_CALL a property in a class which queries a mock.
eg,

    std::string str = "testId";

    EXPECT_CALL(mockSession,
        Load(ElementsAre(Pointee(
                VrmPropVal(std::mem_fun(&VRMGrammarInfoIntf::GetId), 
str))),
            _))
    .WillOnce(Return(VRM_SUCCESS));

    EXPECT_CALL(mockGrammar, GetGrammarID())
    .Times(AtLeast(1))
    .WillRepeatedly(ReturnRef(str));

Where VRMGrammarInfoIntf::GetId will call mockGrammar.GetGrammarId

Which version of Google Mock are you using? On what operating system?
gmock 1.5.0

Please provide any additional information below.

From the callstack below, the global lock is held by 
FindMatchingExpectationAndAction, and then locked again (same thread) in 
SetOwnerAndName. Is it possible to make the mutex recursive? Or is that 
not possible for gmock's supported platforms. Is there a work-around?

Thanks!

(gdb) bt
#0  0x00870402 in __kernel_vsyscall ()
#1  0x00cde0b9 in __lll_lock_wait () from /lib/libpthread.so.0
#2  0x00cd9834 in _L_lock_92 () from /lib/libpthread.so.0
#3  0x00cd934a in pthread_mutex_lock () from /lib/libpthread.so.0
#4  0x08211b9e in testing::internal::MutexBase::Lock (this=0x8392998) at /
root/workspace/root_vobs/gvp_mcp/tests/../tests/gtest-1.5.0/include/gtest/
internal/gtest-port.h:982
#5  0x08211c65 in GTestMutexLock (this=0xbfd4a374, mutex=0x8392998) at /
root/workspace/root_vobs/gvp_mcp/tests/../tests/gtest-1.5.0/include/gtest/
internal/gtest-port.h:1042
#6  0x08286985 in testing::internal::FunctionMockerBase<std::string const& 
()()>::SetOwnerAndName (this=0x8aff828, mock_obj=0x8aff7a0, name=0x832a69d 
"GetGrammarID")
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-spec-builders.h:1415
#7  0x082a89ee in MrInterface::MockMrGrammarInterface::GetGrammarID 
(this=0x8aff7a0) at /root/workspace/root_vobs/gvp_mcp/tests/mocks/
MockMrGrammarInterface.hxx:25
#8  0x082e1c50 in GetId (this=0x8b00700, id=@0xbfd4a3fc) at /root/
workspace/root_vobs/ngms_media/MediaControl/Recognizer/vrm/
VrmRecognizer.cxx:309
#9  0x08268987 in std::const_mem_fun1_t<vrm::VRMStatus, 
vrm::VRMGrammarInfoIntf, std::string&>::operator() (this=0x8affddc, 
__p=0x8b00700, __x=@0xbfd4a3fc)
    at /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/
bits/stl_function.h:672
#10 0x08251d1a in MatchAndExplain (this=0x8affdd8, arg=@0x8b00700, 
result_listener=0xbfd4a458) at /root/workspace/root_vobs/gvp_mcp/tests/
ngms_media/vrm/VrmRecognizerTest.cxx:189
#11 0x08268de2 in testing::internal::MatcherBase<vrm::VRMGrammarInfoIntf 
const&>::MatchAndExplain (this=0x8afe1c4, x=@0x8b00700, 
listener=0xbfd4a458)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:196
#12 0x082d8866 in 
testing::internal::MatchPrintAndExplain<vrm::VRMGrammarInfoIntf, 
vrm::VRMGrammarInfoIntf const&> (value=@0x8b00700, matcher=@0x8afe1c4, 
listener=0xbfd4a594)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:479
#13 0x08241652 in MatchAndExplain (this=0x8afe1c0, pointer=@0x8b00580, 
listener=0xbfd4a594) at /root/workspace/root_vobs/gvp_mcp/tests/../tests/
gmock-1.5.0/include/gmock/gmock-matchers.h:1629
#14 0x082696e2 in testing::internal::MatcherBase<vrm::VRMGrammarInfoIntf* 
const&>::MatchAndExplain (this=0x8afe1a0, x=@0x8b00580, 
listener=0xbfd4a594)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:196
#15 0x082db26e in 
testing::internal::ElementsAreMatcherImpl<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>::MatchAndExplain 
(this=0x8affdf8,
    container=@0xbfd4ac38, listener=0xbfd4a6ec) at /root/workspace/
root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/gmock/gmock-
matchers.h:2265
#16 0x082e5c92 in 
testing::internal::MatcherBase<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>::MatchAndExplain 
(this=0x8afff00, x=@0xbfd4ac38,
    listener=0xbfd4a6ec) at /root/workspace/root_vobs/gvp_mcp/tests/../
tests/gmock-1.5.0/include/gmock/gmock-matchers.h:196
#17 0x082e673f in 
testing::internal::MatcherBase<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>::Matches 
(this=0x8afff00, x=@0xbfd4ac38)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:202
#18 0x082e67be in 
testing::internal::TuplePrefix<1u>::Matches<std::tr1::tuple<testing::Matcher<std
::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>, 
testing::Matcher<vrm::VRMRecoArgsIntf const&>, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass>, 
std::tr1::tuple<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass> > (matcher_tuple=@0x8afff00, 
value_tuple=@0xbfd4abe0)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:500
#19 0x082e67f3 in 
testing::internal::TuplePrefix<2u>::Matches<std::tr1::tuple<testing::Matcher<std
::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>, 
testing::Matcher<vrm::VRMRecoArgsIntf const&>, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass>, 
std::tr1::tuple<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass> > (matcher_tuple=@0x8afff00, 
value_tuple=@0xbfd4abe0)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:500
#20 0x082e6852 in 
testing::internal::TupleMatches<std::tr1::tuple<testing::Matcher<std::vector<vrm
::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&>, 
testing::Matcher<vrm::VRMRecoArgsIntf const&>, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass>, 
std::tr1::tuple<std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, 
std::tr1::_NullClass, std::tr1::_NullClass> > (matcher_tuple=@0x8afff00, 
value_tuple=@0xbfd4abe0)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-matchers.h:573
#21 0x082e7f33 in testing::internal::TypedExpectation<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::Matches (this=0x8affec0, args=@0xbfd4abe0) at /root/workspace/
root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/gmock/gmock-spec-
builders.h:977
#22 0x082e86f8 in testing::internal::TypedExpectation<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::ShouldHandleArguments (this=0x8affec0, args=@0xbfd4abe0) at /
root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/gmock/
gmock-spec-builders.h:990
#23 0x082e8764 in testing::internal::FunctionMockerBase<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::FindMatchingExpectationLocked (this=0x8aff0ec, args=@0xbfd4abe0) 
at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/
gmock/gmock-spec-builders.h:1585
#24 0x082f3030 in testing::internal::FunctionMockerBase<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::FindMatchingExpectationAndAction (this=0x8aff0ec, 
args=@0xbfd4abe0, exp=0xbfd4ab64, action=0xbfd4ab68, 
is_excessive=0xbfd4ab73, what=0xbfd4aaa8, why=0xbfd4a9ec)
    at /root/workspace/root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/
include/gmock/gmock-spec-builders.h:1560
#25 0x082f36c8 in testing::internal::FunctionMockerBase<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::InvokeWith (this=0x8aff0ec, args=@0xbfd4abe0) at /root/workspace/
root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/gmock/gmock-spec-
builders.h:1766
#26 0x082f3d33 in testing::internal::FunctionMocker<vrm::VRMStatus ()
(std::vector<vrm::VRMGrammarInfoIntf*, 
std::allocator<vrm::VRMGrammarInfoIntf*> > const&, vrm::VRMRecoArgsIntf 
const&)>::Invoke
    (this=0x8aff0ec, a1=@0xbfd4ac38, a2=@0xbfd4ac48) at /root/workspace/
root_vobs/gvp_mcp/tests/../tests/gmock-1.5.0/include/gmock/gmock-generated-
function-mockers.h:116
#27 0x082f3d6f in Recognizer::VrmAsrManager::Session::Load 
(this=0x8aff0ec, gmock_a1=@0xbfd4ac38, gmock_a2=@0xbfd4ac48)
    at /root/workspace/root_vobs/gvp_mcp/tests/mocks/Recognizer/vrm/
VrmAsrManager.hxx:23
#28 0x082e2e4c in Recognizer::VrmRecognizer::LoadRecognition 
(this=0x8aff0c8, ar_recoInfo=@0x8aff260) at /root/workspace/root_vobs/
ngms_media/MediaControl/Recognizer/vrm/VrmRecognizer.cxx:463
#29 0x082e0cec in DtmfRecognizerBase::LoadReco (this=0x8afed80) at /root/
workspace/root_vobs/gvp_mcp/tests/ngms_media/vrm/VrmRecognizerTest.cxx:143
#30 0x08250e48 in DtmfRecognizerTest_LoadRecognitionGetId_Test::TestBody 
(this=0x8afed78) at /root/workspace/root_vobs/gvp_mcp/tests/ngms_media/vrm/
VrmRecognizerTest.cxx:315
#31 0x082fece8 in testing::Test::Run ()

Original issue reported on code.google.com by s22c...@gmail.com on 31 May 2010 at 3:37

GoogleCodeExporter commented 9 years ago
gmock doesn't intend to support this kind of usage.  In general, matchers 
cannot have
side effects, as gmock doesn't guarantee how many times a matcher will be 
invoked. 
In this example, one matcher has the side effect of invoking a mock method, 
which
will affect the state of the mock object.  Please try to rewrite the code to 
avoid
invoking a mock method in a matcher.

Original comment by w...@google.com on 1 Jun 2010 at 6:26