【发布时间】:2010-09-11 15:51:48
【问题描述】:
我的 C 应用程序使用第三个库,它们自己管理内存。 为了更健壮,我的应用程序有代码来处理由于缺少可用内存而导致的库函数失败。
我想测试这段代码,为此,我需要模拟由于内存不足而导致的失败。
为此推荐什么工具? 我的环境是Linux/gcc。
【问题讨论】:
标签: c linux unit-testing gcc memory-management
我的 C 应用程序使用第三个库,它们自己管理内存。 为了更健壮,我的应用程序有代码来处理由于缺少可用内存而导致的库函数失败。
我想测试这段代码,为此,我需要模拟由于内存不足而导致的失败。
为此推荐什么工具? 我的环境是Linux/gcc。
【问题讨论】:
标签: c linux unit-testing gcc memory-management
您可以使用ulimit 来限制用户可以使用的资源量,包括内存。因此,您创建了一个测试用户,将他们的内存使用限制在足以启动您的程序的范围内,然后看着它死掉:)
例子:
ulimit -m 64
将内存限制设置为 64kb。
【讨论】:
创建您自己的 malloc 包装器,它将随机返回 null 而不是有效指针。好吧,或者如果你想进行单元测试,它会一直失败。
【讨论】:
calloc、realloc、strdup,以及代码使用的任何其他内存分配函数。而且你会想要一种在构建发布时关闭此功能的方法。
在过度使用内存的操作系统(例如 Linux 或 Windows)上,根本不可能处理内存不足错误。 malloc 可能会返回一个有效的指针,稍后,当您尝试取消引用它时,您的操作系统可能会确定您内存不足并终止该进程。
http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/ 是一篇很好的文章。
【讨论】:
ulimit 或整个虚拟地址空间的耗尽也可能导致分配失败。
您可以编写自己的模拟库,使用与您的第 3 方库相同的界面来代替它。您还可以使用 LD_PRELOAD 覆盖 3rd 方库的选定函数。
【讨论】:
我可以给出一个 Linux(也许是 POSIX)特定版本:__malloc_hook、__realloc_hook、__free_hook。这些在 malloc.h 中声明。
编辑:稍加说明:这些是函数指针(有关确切声明,请参见 malloc.h 及其手册页),但请注意:这些并不完全是标准,只是 GNU 扩展。因此,如果便携性是一个问题,请不要使用它。
与平台无关的解决方案可能是声明一个 malloc 宏。如果您正在测试,这将调用一个钩子和真正的 malloc。
memhook.h:
#define malloc(s) (my_malloc(s))
memhook.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 命令。尝试
help ulimit在 bash shell 提示符下。
【讨论】:
(作为之前一些答案的补充)
查看“Electric Fence”以获取可以与可执行文件一起使用的 malloc 拦截库的示例(例如,使用 LD_PRELOAD 技巧)。
一旦你拦截了 malloc,你可以使用任何你想触发失败的东西。随机触发的故障将是对系统各个部分的良好压力测试。您还可以根据请求的内存量修改失败概率。
顺便说一句,你的想法很有趣,显然我想对我的一些代码做一些事情......
【讨论】:
您可能想查看一些面向恢复的计算站点,例如Berkeley/Stanford ROC group。我之前听过其中一些人的谈话,他们使用代码在 C 运行时中随机注入错误。在他们的页面底部有一个指向他们的 FIT 工具的链接。
【讨论】:
看看the way sqlite3 does this。他们执行广泛的单元测试,包括内存不足测试。
您可能还想查看their page on malloc,尤其是Section 4.0。
【讨论】: