我的 C 应用程序使用第三个库,它们自己管理内存。为了变得健壮,我的应用程序有代码来处理由于缺少可用内存而导致的库函数故障。
我想测试这段代码,为此,我需要模拟由于内存不足而导致的失败。
为此推荐什么工具?我的环境是 Linux/gcc。
我的 C 应用程序使用第三个库,它们自己管理内存。为了变得健壮,我的应用程序有代码来处理由于缺少可用内存而导致的库函数故障。
我想测试这段代码,为此,我需要模拟由于内存不足而导致的失败。
为此推荐什么工具?我的环境是 Linux/gcc。
您可以ulimit
用来限制用户可以使用的资源量,包括内存。因此,您创建了一个测试用户,将他们的内存使用限制在足以启动您的程序的范围内,然后看着它死掉:)
例子:
ulimit -m 64
将内存限制设置为 64kb。
创建您自己的 malloc 包装器,它将随机返回 null 而不是有效指针。好吧,或者如果你想进行单元测试,它会一直失败。
在过度使用内存的操作系统(例如,Linux 或 Windows)上,根本不可能处理内存不足错误。malloc 可能会返回一个有效的指针,稍后,当您尝试取消引用它时,您的操作系统可能会确定您内存不足并终止该进程。
http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/是一篇很好的文章。
您可以编写自己的模拟库,使用与您的 3rd 方库相同的接口来代替它。您还可以使用 LD_PRELOAD 覆盖 3rd 方库的选定函数。
我可以给出一个 Linux(可能是 POSIX)特定版本:__malloc_hook、__realloc_hook、__free_hook。这些在 malloc.h 中声明。
编辑:稍微详细说明一下:这些是函数指针(有关确切声明,请参见 malloc.h 及其手册页),但请注意:这些并不完全是标准,只是 GNU 扩展。因此,如果可移植性是一个问题,请不要使用它。
与平台无关的解决方案可能是您声明了一个 malloc 宏。如果您正在测试,这将调用一个钩子和真正的 malloc。
内存挂钩.h:
#define malloc(s) (my_malloc(s))
内存挂钩.c:
#include "memhook.h"
#undef malloc
#include <stdlib.h>
等等
您可以使用它来检测泄漏、随机分配失败等。
此外,你应该使用Valgrind来测试它并获得关于你的程序的内存行为的真正有用的报告
您可以在头文件中设置一个定义,以便在使用 malloc 时返回 NULL:
通常 malloc 将通过以下方式受到保护:
if ((int *x = malloc(sizeof(int))) == NULL)
{
return NULL;
}
因此,您使用定义来强制返回 NULL;伪代码示例:
# define malloc(X) NULL
并检查您是否遇到段错误
您需要 bash 中的 ulimit 命令。尝试
帮助超限在 bash shell 提示符下。
您可能想查看一些面向恢复的计算站点,例如Berkeley/Stanford ROC group。我以前听过其中一些人的谈话,他们使用代码在 C 运行时中随机注入错误。在他们的页面底部有一个指向他们的 FIT 工具的链接。
(作为对之前一些答案的补充)
查看“Electric Fence”以获取可以与可执行文件一起使用的 malloc 拦截库的示例(例如,使用 LD_PRELOAD 技巧)。
一旦你拦截了 malloc,你可以使用任何你想触发失败的东西。随机触发的故障将是对系统各个部分的良好压力测试。您还可以根据请求的内存量修改故障概率。
顺便说一句,你的想法很有趣,显然我想对我的一些代码做一些事情......
看看sqlite3 是如何做到这一点的。他们执行广泛的单元测试,包括内存不足测试。
您可能还想查看他们关于 malloc 的页面,尤其是第 4.0 节。