eranpeer / FakeIt

C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.
MIT License
1.23k stars 169 forks source link

FakeIt crashes when creating Mock on gcc + optimization #156

Closed mfontanini closed 5 years ago

mfontanini commented 5 years ago

The following trivial code sample blows up on Mock's constructor when building using any optimization level (e.g. -O2 or -O3) on gcc. If I remove the optimization level, it works just fine:

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include <catch/fakeit.hpp>

class Foo {
public:
    virtual ~Foo() = default;
};

TEST_CASE("test") {
    fakeit::Mock<Foo> mocked; // < kaboom
}

The valgrind output shows:

==29464== Invalid write of size 8
==29464==    at 0x446BFB: setMethod (fakeit.hpp:5690)
==29464==    by 0x446BFB: initAll (fakeit.hpp:5775)
==29464==    by 0x446BFB: fakeit::MockImpl<Foo<> >::createFakeInstance() (fakeit.hpp:8181)
==29464==    by 0x41ED38: MockImpl (fakeit.hpp:7956)
==29464==    by 0x41ED38: Mock (fakeit.hpp:8294)
==29464==    by 0x41ED38: ____C_A_T_C_H____T_E_S_T____0() (test.cpp:11)
==29464==    by 0x40A711: invoke (catch.hpp:10232)
==29464==    by 0x40A711: Catch::RunContext::invokeActiveTestCase() (catch.hpp:9104)
==29464==    by 0x417EF7: Catch::RunContext::runCurrentTest(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (catch.hpp:9078)
==29464==    by 0x42968D: Catch::RunContext::runTest(Catch::TestCase const&) (catch.hpp:8861)
==29464==    by 0x429CC3: Catch::(anonymous namespace)::runTests(std::shared_ptr<Catch::Config> const&) [clone .constprop.2013] (catch.hpp:9394)
==29464==    by 0x42BC14: Catch::Session::runInternal() (catch.hpp:9592)
==29464==    by 0x42BCF9: Catch::Session::run() (catch.hpp:9549)
==29464==    by 0x405544: run (catch.hpp:9517)
==29464==    by 0x405544: main (catch.hpp:13054)
==29464==  Address 0x5b0e060 is 0 bytes after a block of size 48 alloc'd
==29464==    at 0x4C2E87B: operator new[](unsigned long) (vg_replace_malloc.c:423)
==29464==    by 0x446BB5: buildVTArray (fakeit.hpp:5793)
==29464==    by 0x446BB5: VirtualTable (fakeit.hpp:5735)
==29464==    by 0x446BB5: fakeit::MockImpl<Foo<> >::createFakeInstance() (fakeit.hpp:5848)
==29464==    by 0x41ED38: MockImpl (fakeit.hpp:7956)
==29464==    by 0x41ED38: Mock (fakeit.hpp:8294)
==29464==    by 0x41ED38: ____C_A_T_C_H____T_E_S_T____0() (test.cpp:11)
==29464==    by 0x40A711: invoke (catch.hpp:10232)
==29464==    by 0x40A711: Catch::RunContext::invokeActiveTestCase() (catch.hpp:9104)
==29464==    by 0x417EF7: Catch::RunContext::runCurrentTest(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (catch.hpp:9078)
==29464==    by 0x42968D: Catch::RunContext::runTest(Catch::TestCase const&) (catch.hpp:8861)
==29464==    by 0x429CC3: Catch::(anonymous namespace)::runTests(std::shared_ptr<Catch::Config> const&) [clone .constprop.2013] (catch.hpp:9394)
==29464==    by 0x42BC14: Catch::Session::runInternal() (catch.hpp:9592)
==29464==    by 0x42BCF9: Catch::Session::run() (catch.hpp:9549)
==29464==    by 0x405544: run (catch.hpp:9517)
==29464==    by 0x405544: main (catch.hpp:13054)

This is using FakeIt 2.0.5 and gcc 5.4.0.

mfontanini commented 5 years ago

This seems to be a duplicate of https://github.com/eranpeer/FakeIt/issues/84.