Gmock race when setting expectations

331 views
Skip to first unread message

Francois Echantillac

unread,
Sep 28, 2016, 5:10:02 PM9/28/16
to googl...@googlegroups.com, Ming Zhao
Hello,

Using Clang thread sanitizer with gmock 1.7.0 I'm facing a race in the
gmock library. I built a mock which is used by a thread (T2 here), then
trying to set an expectation on it using the EXPECT_CALL macro. Tsan
doesn't seem happy about it, see below for the relevant portions of the
stacktraces.
From what I can tell it looks like the race happens on
untyped_expectations_ as its access is not protected.
Is that a bug or is that use case unsupported ?

Thank you!
Francois


WARNING: ThreadSanitizer: data race (pid=1)

Read of size 8 at 0x7d700001b9c8 by thread T2 (mutexes: write M156):
#0
std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>,
std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase>
> >::size() const
/usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/stl_vector.h:728:2
(x2gw-simple-enb_test+0x000000a4219b)
#1
testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void
const*)
/usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/src/gmock-spec-builders.cc:338:7
(x2gw-simple-enb_test+0x000000db7bcb)
#2 testing::internal::FunctionMockerBase<void
(net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*)>::InvokeWith(std::tuple<net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*> const&)
/usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1585:34
(x2gw-simple-enb_test+0x000000a61444)
#3 testing::internal::FunctionMocker<void
(net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*)>::Invoke(net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*)
/usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-generated-function-mockers.h:125:12
(x2gw-simple-enb_test+0x000000a613ff)
...

Previous write of size 8 at 0x7d700001b9c8 by main thread:
#0 void
std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>,
std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase>
>
>::_M_emplace_back_aux<testing::internal::linked_ptr<testing::internal::ExpectationBase> const&>(testing::internal::linked_ptr<testing::internal::ExpectationBase> const&) /usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/vector.tcc:479:2 (x2gw-simple-enb_test+0x000000a41fc5)
#1
std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>,
std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase>
>
>::push_back(testing::internal::linked_ptr<testing::internal::ExpectationBase> const&) /usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/stl_vector.h:1049:4 (x2gw-simple-enb_test+0x000000a419c7)
#2 testing::internal::FunctionMockerBase<void
(net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*)>::AddNewExpectation(char const*, int,
std::string const&,
std::tuple<testing::Matcher<net::masc::AsnContext<lte::X2apProtoParams>*>,
testing::Matcher<x2ap::ENBConfigurationUpdate*> > const&)
/usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1611:5
(x2gw-simple-enb_test+0x000000a417b2)
#3 testing::internal::MockSpec<void
(net::masc::AsnContext<lte::X2apProtoParams>*,
x2ap::ENBConfigurationUpdate*)>::InternalExpectedAt(char const*, int,
char const*, char const*)
/usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1272:12
(x2gw-simple-enb_test+0x000000a3f678)
...

Samuel Benzaquen

unread,
Sep 28, 2016, 5:15:03 PM9/28/16
to Francois Echantillac, Google C++ Mocking Framework, Ming Zhao
On Wed, Sep 28, 2016 at 4:34 PM, Francois Echantillac <fran...@luminatewireless.com> wrote:
Hello,

Using Clang thread sanitizer with gmock 1.7.0 I'm facing a race in the gmock library. I built a mock which is used by a thread (T2 here), then trying to set an expectation on it using the EXPECT_CALL macro. Tsan doesn't seem happy about it, see below for the relevant portions of the stacktraces.
From what I can tell it looks like the race happens on untyped_expectations_ as its access is not protected.
Is that a bug or is that use case unsupported ?

You can't set expectations while the mock object is in use.
Even if we added synchronization in the framework you would still have race conditions on the application level, which is shown by the TSan failure.

---
Important note: Google Mock requires expectations to be set before the mock functions are called, otherwise the behavior is undefined. In particular, you mustn't interleave EXPECT_CALL()s and calls to the mock functions.
---
 

Thank you!
Francois


WARNING: ThreadSanitizer: data race (pid=1)

Read of size 8 at 0x7d700001b9c8 by thread T2 (mutexes: write M156):
    #0 std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>, std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase> > >::size() const /usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/stl_vector.h:728:2 (x2gw-simple-enb_test+0x000000a4219b)
    #1 testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) /usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/src/gmock-spec-builders.cc:338:7 (x2gw-simple-enb_test+0x000000db7bcb)
    #2 testing::internal::FunctionMockerBase<void (net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*)>::InvokeWith(std::tuple<net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*> const&) /usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1585:34 (x2gw-simple-enb_test+0x000000a61444)
    #3 testing::internal::FunctionMocker<void (net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*)>::Invoke(net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*) /usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-generated-function-mockers.h:125:12 (x2gw-simple-enb_test+0x000000a613ff)
...

 Previous write of size 8 at 0x7d700001b9c8 by main thread:
    #0 void std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>, std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase> > >::_M_emplace_back_aux<testing::internal::linked_ptr<testing::internal::ExpectationBase> const&>(testing::internal::linked_ptr<testing::internal::ExpectationBase> const&) /usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/vector.tcc:479:2 (x2gw-simple-enb_test+0x000000a41fc5)
    #1 std::vector<testing::internal::linked_ptr<testing::internal::ExpectationBase>, std::allocator<testing::internal::linked_ptr<testing::internal::ExpectationBase> > >::push_back(testing::internal::linked_ptr<testing::internal::ExpectationBase> const&) /usr/crosstool/v2/gcc-4.9.1-lrtev1/x86/lib/gcc/x86_64-unknown-linux-gnu/4.9.x-google/../../../../include/c++/4.9.x-google/bits/stl_vector.h:1049:4 (x2gw-simple-enb_test+0x000000a419c7)
    #2 testing::internal::FunctionMockerBase<void (net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*)>::AddNewExpectation(char const*, int, std::string const&, std::tuple<testing::Matcher<net::masc::AsnContext<lte::X2apProtoParams>*>, testing::Matcher<x2ap::ENBConfigurationUpdate*> > const&) /usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1611:5 (x2gw-simple-enb_test+0x000000a417b2)
    #3 testing::internal::MockSpec<void (net::masc::AsnContext<lte::X2apProtoParams>*, x2ap::ENBConfigurationUpdate*)>::InternalExpectedAt(char const*, int, char const*, char const*) /usr/local/home/_bazel_francois/189fc812c7ed18873b09b97c3ce9a0d2/main/third_party/google/gmock/include/gmock/gmock-spec-builders.h:1272:12 (x2gw-simple-enb_test+0x000000a3f678)
...


--

--- You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/googlemock/57EC2960.1080309%40luminatewireless.com.
For more options, visit https://groups.google.com/d/optout.

Francois Echantillac

unread,
Sep 28, 2016, 5:35:40 PM9/28/16
to Samuel Benzaquen, Google C++ Mocking Framework, Ming Zhao
Fair enough. Thanks for the pointer, I overlooked that important note :)
Reply all
Reply to author
Forward
0 new messages