google / benchmark

A microbenchmark support library
Apache License 2.0
8.59k stars 1.57k forks source link

[BUG] Fixture test with StrictMock crashed #1780

Closed rikiwow closed 2 months ago

rikiwow commented 2 months ago

Describe the bug I met an issue similar as https://github.com/google/benchmark/issues/1201. If benchmark Fixture includes StrictMock class, running it will get Segmentation fault. The crash seems happens when constructing StrictMock objects. Please check the gdb backtrace at the end.

System

To reproduce The code is as below:

#include "gmock/gmock.h"
#include <benchmark/benchmark.h>
using namespace testing;

class Foo {
public:
    virtual ~Foo() {}
    virtual void set() const = 0;
};

class MockFoo : public Foo {
    public:
        MOCK_METHOD(void, set, (), (const, override));
};

class TestBM: public benchmark::Fixture
{
    public:
        void SetUp(::benchmark::State& state) {
        }

        void TearDown(::benchmark::State& state) {
        }
        StrictMock<MockFoo> mock; //remove this line, testing pass
};

BENCHMARK_DEFINE_F(TestBM, TestcaseName)(benchmark::State& state)
{
    for (auto _ : state)
    {
        int sum = 0;
        for (int i=0; i< 100; i++)
            sum += i;
    }
}

BENCHMARK_REGISTER_F(TestBM, TestcaseName)->Threads(2);

BENCHMARK_MAIN();

Additional context gdb backtrace:

(gdb) bt

0 0x00007ffff609bdee in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) ()

from /fakepath/sdk-qemux86-64/tmp/sysroots/qemux86-64/usr/lib64/libstdc++.so.6

1 0x0000000000736f0b in std::_Rb_tree_iterator<std::pair<void const* const, testing::internal::CallReaction> >::operator--() ()

2 0x0000000000736e60 in std::_Rb_tree<void const, std::pair<void const const, testing::internal::CallReaction>, std::_Select1st<std::pair<void const const, testing::internal::CallReaction> >, std::less<void const>, std::allocator<std::pair<void const const, testing::internal::CallReaction> > >::_M_get_insert_unique_pos(void const const&) ()

3 0x0000000000734fdb in std::_Rb_tree<void const, std::pair<void const const, testing::internal::CallReaction>, std::_Select1st<std::pair<void const const, testing::internal::CallReaction> >, std::less<void const>, std::allocator<std::pair<void const const, testing::internal::CallReaction> > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<void const const, testing::internal::CallReaction> >, void const* const&) ()

4 0x0000000000733108 in std::_Rb_tree_iterator<std::pair<void const const, testing::internal::CallReaction> > std::_Rb_tree<void const, std::pair<void const const, testing::internal::CallReaction>, std::_Select1st<std::pair<void const const, testing::internal::CallReaction> >, std::less<void const>, std::allocator<std::pair<void const const, testing::internal::CallReaction> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<void const const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<void const const, testing::internal::CallReaction> >, std::piecewise_construct_t const&, std::tuple<void const* const&>&&, std::tuple<>&&)

()

5 0x0000000000730e10 in std::map<void const, testing::internal::CallReaction, std::less<void const>, std::allocator<std::pair<void const const, testing::internal::CallReaction> > >::operator[](void const const&) ()

6 0x000000000072c0a3 in testing::(anonymous namespace)::SetReactionOnUninterestingCalls(void const*, testing::internal::CallReaction) ()

7 0x000000000072c133 in testing::Mock::FailUninterestingCalls(void const*) ()

8 0x0000000000663941 in TestBM_TestcaseName_Benchmark::TestBM_TestcaseName_Benchmark() ()

9 0x00000000005b68e7 in _GLOBAL__sub_I_fake.cpp ()

10 0x00007ffff5d24fee in __libc_start_main () from /fakepath/sdk-qemux86-64/tmp/sysroots/qemux86-64/usr/lib64/libc.so.6

11 0x00000000005bc615 in _start ()

LebedevRI commented 2 months ago

Sounds like google test does not expect to be run from multiple threads. I'd recommend reporting that in their repo.

dmah42 commented 2 months ago

agreed that this is an issue with the StrictMock implementation rather than benchmarks, given the only difference is the inclusion of the StrictMock instance.