eranpeer / FakeIt

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

upcast using dynamic_cast of a fake fails #196

Open Iqon opened 4 years ago

Iqon commented 4 years ago

Given I have the following two classes a base class Base and a class Test which derives from Base.

class Base
{
public:
    virtual void Method1()
    {}
};

class Test : public Base
{
public:
    virtual void Method2()
    { }
};

If I create a fake of Test and then try to upcast a pointer of type Base which points to the fake back to Test* if throws an exception.

fakeit::Mock<Test> testStub;
Base *ptr = &testStub();
Base *c2 = dynamic_cast<Test*>(ptr); // this throws an exception.

The last line throws an expection with the following message:

Exception thrown at 0x00007FFC352F7517 (vcruntime140d.dll) in AppName.exe: 0xC0000005: Access violation reading location 0x0000000000000004.

wickeat commented 3 years ago

Bump.

wickeat commented 3 years ago

Bump

malcolmdavey commented 2 years ago

Just reproduced it with VS 2019/v142 (debug) compiler - so still an issue it seems

C++ exception with description "Access violation - no RTTI data!

FranckRJ commented 2 years ago

I guess it's because the RTTI isn't properly set up for the mock. I have to idea if it's something that is hard to implement or not (because it's compiler-specific), but I would like to know, what use case do you have for that feature ? As maybe there is a workaround.

FranckRJ commented 2 years ago

Oh ok it's a feature of FakeIt, it's supposed to work, didn't knew : https://github.com/eranpeer/FakeIt/wiki/Quickstart#inheritance--dynamic-casting

otrempe commented 1 year ago

+1

malcolmdavey commented 1 year ago

Visual C++ has an option to turn on or off RTTI, but it makes no difference to this problem.

I'm assuming the implementation just isn't working correctly for Visual C++ - might need to look at all the assembly/and memory layout etc

2 of the Fakeit unit tests have this problem on windows.

[--------------]
[ RUN          ] TypeInfoTests::mock_should_use_same_typeid_as_mocked_class
[              ]    exception #2 from TypeInfoTests::mock_should_use_same_typeid_as_mocked_class with cause: Bad read pointer - no RTTI data!
[       FAILED ] TypeInfoTests::mock_should_use_same_typeid_as_mocked_class
[ RUN          ] TypeInfoTests::simple_inheritance_upcast
[       PASSED ] TypeInfoTests::simple_inheritance_upcast
[ RUN          ] TypeInfoTests::dynamic_cast_to_same_type__with_concrete_type
[       PASSED ] TypeInfoTests::dynamic_cast_to_same_type__with_concrete_type
[ RUN          ] TypeInfoTests::dynamic_cast_to_same_type__with_abstract_type
[       PASSED ] TypeInfoTests::dynamic_cast_to_same_type__with_abstract_type
[ RUN          ] TypeInfoTests::simple_inheritance_dynamic_down_cast
[              ]    exception #3 from TypeInfoTests::simple_inheritance_dynamic_down_cast with cause: Access violation - no RTTI data!
[       FAILED ] TypeInfoTests::simple_inheritance_dynamic_down_cast
[--------------]
malcolmdavey commented 1 year ago

This is maybe the reason that the tests in struct GccTypeInfoTests: tpunit::TestFixture are not run on windows, as it also fails for what seems to be the same root cause.

[ RUN          ] GccTypeInfoTests::simple_inheritance_dynamic_down_cast
[              ]    exception #1 from GccTypeInfoTests::simple_inheritance_dynamic_down_cast with cause: Access violation - no RTTI data!
[       FAILED ] GccTypeInfoTests::simple_inheritance_dynamic_down_cast
jussi-muhonen-nexstim commented 1 year ago

+1

msimard75 commented 1 year ago

+1

FranckRJ commented 1 year ago

To add a bit more information about this, it's bugged only when compiling in 64 bits. If you compile in 32 bits it works fine (at least the tests pass).

malcolmdavey commented 1 year ago

Makes sense. I'm 99% compiling 64bit