如何模拟内存分配错误
我的C应用程序使用第3个库,它们执行自己的内存管理。
为了保持健壮性,我的应用程序具有用于处理由于缺少可用内存而导致的库函数故障的代码。
我想测试此代码,为此,我需要模拟由于内存不足而导致的故障。
建议使用什么工具?
我的环境是Linux / gcc。
解决方案
创建我们自己的malloc包装器,该包装器将随机返回null而不是有效的指针。好吧,否则,如果要进行单元测试,它将始终失败。
我们可以编写自己的模拟库,而不是使用与第三方库相同的接口。我们也可以使用LD_PRELOAD覆盖第3方库的选定功能。
我可以提供一个特定于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>
等等。
我们可以使用它来检测泄漏,随机分配失败等。
我们可以使用ulimit来限制用户可以使用的资源量,包括内存。因此,我们创建了一个测试用户,将他们的内存使用限制为刚好足以启动程序,并看着它消亡:)
例子:
ulimit -m 64
将内存限制设置为64kb。
我们需要在bash中使用ulimit命令。尝试
help ulimit
在bash shell提示下。
此外,我们应该使用Valgrind对其进行测试,并获得有关程序的内存行为的真实有用的报告。
(作为对先前答案的补充)
检出"电子围栏",以获取可与可执行文件一起使用的malloc拦截库的示例(例如,使用LD_PRELOAD技巧)。
一旦拦截了malloc,就可以使用任何想要触发故障的东西。对于系统的各个部分,随机触发的故障将是一个很好的压力测试。我们还可以根据请求的内存量来修改故障概率。
顺便说一句,想法很有趣,显然是我想对某些代码进行的操作...
在过度使用内存的操作系统(例如Linux或者Windows)上,根本无法处理内存不足错误。 malloc可能会返回一个有效的指针,稍后,当我们尝试取消引用它时,操作系统可能会确定我们内存不足并杀死该进程。
http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/是一个很好的文章。
我们可能需要查看一些面向恢复的计算站点,例如Berkeley / Stanford ROC组。我以前听过其中一些人的谈话,他们使用代码在C运行时中随机注入错误。页面底部有一个指向其FIT工具的链接。
看看sqlite3做到这一点的方式。他们执行广泛的单元测试,包括内存不足测试。
我们可能还需要查看他们在malloc上的页面,特别是第4.0节。