Skip to content

"Return-location" of called Base-Class-method is wrong #353

@Seim2k17

Description

@Seim2k17

Hi,

as I'm not sure if this is an issue with 'Fakeit' I would label this as an question.

Problem:

When using Fakeit to Mock a class B, which is inherited from Class A which have non-virtual-methods, which are called from a test I get an SEGFAULT. That's because (regarding to GDB) in its call-chain at some point it steps through certain branches, goes into other methods and when it returns the returned location is somewhere else in the code and then the code does things which it doesn't suppose to do at this point. I would call this undefined behavior.

Is this kind of issue known somehow?

When I make the method (log_error) virtual I can overwrite this with a mock in the testcase and the test passes as it should.
But unfortunately this is not so easily possible because its a legacy code-base and Class A comes from an external library, and not the library I'm working on to extend it with tests. This would also be problematic because then these log-methods are then marked to be overridden, and that's what we want to avoid.

Situation in code:

class A
{
 public:
  explicit A(...);
  virtual ~A();
  ...
  void log_error(std::stringview msg, ...);
};

class B : public A
{
 public:
   virtual void process(int command)
   {
      if(command == 1)
      {
          log_error("Error occured");
      }
      else ...
   }
}

Test:

TEST_CASE("Add block", "[block_add]")
{
   using namespace fakeit;

    Mock<B> mock_B;
    
    // When(OverloadedMethod(mock_B, log_error, void(std::string_view))).Return();

    When(Method(mock_B, make_trans)).Return(0);

    // call the real implementation
    When(Method(mock_B, process_event)).AlwaysDo([&mock_B](int cmd){
      return mock_B.get().B::process(cmd);
    });

    mock_B.get().process(1);  // it will crash when calling log_error() which is part of class A
}

In GDB at some point it marks the source-code in TUI completely red, which typically indicate that the program counter has moved outside the known code.

Environment:

  • Ubuntu24
  • using Catch2 v3.8 for unittests
  • GDB v15.0.50
  • C++17
  • legacy codebase split across many libraries (including C-code as well as C++-code)

Thank you in advance.

Best,
Seim

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions