在单元测试中检测特定函数调用

Jea*_*ier 8 c c++ linux unit-testing dynamic-analysis

我希望能够检测我的函数(或它调用的任何其他函数)是否最终会在我的单元测试中调用某些特定函数(例如,mallocfree):我的软件的一小部分具有硬实时要求,并且我想确保没有人添加会在这些函数中偶然触发分配的东西(并让我的CI管道自动检查它).

我知道我可以在gdb上设置一个断点,但理想情况下我想做的事情如下:

void my_unit_test() {
    my_object obj; // perform some initialization that will allocate

    START_CHECKING_FUNCTION(malloc); // also, operator new or std::allocate would be nice
    obj.perform_realtime_stuff();
    STOP_CHECKING_FUNCTION(malloc);
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,std::abort如果在两个检查之间调用malloc ,那么测试将以不太脏的方式(例如不是)失败.

理想情况下,这可以在任何系统上运行,但我现在可以使用只在Linux上运行的东西.这有可能吗?也许通过LD_PRELOAD hack来取代malloc,但我不想为我感兴趣的所有函数做这个.

OwO*_*OwO 1

如果您正在使用调用 malloc 的库,那么您可能需要查看Joint Strike Fighter C++ Coding Standards。这是一种针对任务关键型软件的编码风格。一种建议是编写您自己的分配器。另一个建议是使用类似jemalloc具有统计数据的东西,但更不可预测,因为它是针对性能的。


您想要的是一个具有间谍功能的模拟库。每个框架的工作原理都会有所不同,但这里是一个使用 Google 的示例:

static std::function<void*(size_t)> malloc_bridge;

struct malloc_mock {
    malloc_mock() { malloc_bridge = std::bind(&malloc_mock::mock_, this, _1); }
    MOCK_METHOD1(mock_, void*(size_t));
}

void* malloc_cheat(size_t size) {
    return malloc_bridge(size);
}

#define malloc malloc_cheat

struct fixture {
    void f() { malloc(...); }
};

struct CustomTest : ::testing::test {
    malloc_mock mock_;
};

TEST_F(CustomTest, ShouldMallocXBytes) {
    EXPECT_CALL(mock_, mock_(X))
      .WillOnce(::testing::Return(static_cast<void*>(0)));
    Fixture fix;
    fix.f();
}

#undef malloc
Run Code Online (Sandbox Code Playgroud)

警告:编译器尚未触及代码。但你明白了。