测试内存分配失败时的正确行为

Testing for proper behaviour on memory allocation failures

本文关键字:内存 分配 失败 测试      更新时间:2023-10-16

我们有一个相对较大的Linux服务器代码库,它是动态链接的库和服务器模块,在启动时使用dlopen()加载。服务器和大多数其他组件都是用c++ 11编写的,但有些是用C99编写的。

什么方法可以用来测试服务器,它的依赖关系和模块是否正确处理内存分配失败,例如malloc/calloc返回NULL,操作符newnew[]抛出std::bad_alloc等,包括std::string::resize()的分配失败等等?

在过去,我曾尝试使用内存分配挂钩将内存分配失败注入C应用程序,但我认为这些对c++不起作用。我应该考虑哪些其他选择或方法?

实际上,连接到C的malloc就足够了,因为在底层,gcc c++的operator new的默认实现确实调用了malloc,并且您确认您只需要一个gcc兼容的解决方案。

我可以用下面这个简单的程序来演示:

mem.c + +:

#include <iostream>
#include <string>
class A {
    int ival;
    std::string str;
public:
    A(int i, std::string s): ival(i), str(s) {}
    A(): ival(0), str("") {};
    int getIval() const {
        return ival;
    }
    std::string getStr() const {
        return str;
    }
};
int main() {
    A a(2, "foo");
    std::cout << &a << " : " << a.getIval() << " - " << a.getStr() << std::endl;
    return 0;
}

memhook.c:

#include <stdio.h>
#include <stdlib.h>
extern void *__libc_malloc(size_t size);
void* malloc (size_t size) {
    fprintf(stderr, "Allocating %un", size);
    return NULL;
//    return __libc_malloc(size);
}

当返回NULL(如上)时,程序显示:

Allocating 16
Allocating 100
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Abandon (core dumped)

证明从声明的malloc函数返回NULL会导致c++代码中的std::bad_alloc异常

当取消注释return __libc_malloc(size);时,分配由libc malloc完成,输出变为:

Allocating 16
0xbfe8d2e8 : 2 - foo

在linux上,您可以挂接到操作系统来强制分配失败

man 2 mlockall

mlockall(MCL_CURRENT|MCL_FUTURE);

应该做你想做的