eranpeer / FakeIt

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

Mocks with nested interfaces having non-virtual destructors cause SEGV #123

Closed dcopp closed 2 years ago

dcopp commented 6 years ago

Thank you for making this very well done framework! Love using it.

This issue likely isn't fixable but perhaps deserves emphasis in doc: mocking an interface's virtual destructor requires all of its parent interfaces, if any, to also have virtual destructors -- otherwise the mock dtor will SEGV.

Repro sample:

#include "fakeit.hpp"
#include <memory>
#include <functional>
#include <iostream>

using namespace fakeit;
using namespace std;

// Composition via nested interface with default (non-virtual) destructor

struct Interface1
{
    virtual void foo() = 0;
};

struct Interface2 : public Interface1
{
    virtual ~Interface2() {}
    virtual void bar() = 0;
};

struct S : public Interface2 {
    virtual ~S() {}
    void foo() {}
    void bar() {}
};

unique_ptr<Interface2, function<void(Interface2*)>> ptr(nullptr, [](Interface2 *i){ delete i; });

int main() {

    ptr.reset(new S);
    ptr.reset(); // Ok
    cout << "Non-mock new/delete ok" << endl;

    Mock<Interface2> mock;
    Fake(Dtor(mock));

    ptr.reset(&mock.get());
    ptr.reset(); // SEGV
    cout << "Mock new/delete ok" << endl;

}
FranckRJ commented 2 years ago

Seems to have been fixed in FakeIt 2.0.5, I don't know which PR tho.

If it wasn't really fixed, please re-open the issue (or re-create one if you can't).