如何模拟内存分配错误
Posted
技术标签:
【中文标题】如何模拟内存分配错误【英文标题】:How to simulate memory allocation errors 【发布时间】:2010-09-11 15:51:48 【问题描述】:我的 C 应用程序使用第三个库,它们自己管理内存。 为了更健壮,我的应用程序有代码来处理由于缺少可用内存而导致的库函数失败。
我想测试这段代码,为此,我需要模拟由于内存不足而导致的失败。
为此推荐什么工具? 我的环境是Linux/gcc。
【问题讨论】:
另见***.com/questions/1229241/… 【参考方案1】:您可以使用ulimit
来限制用户可以使用的资源量,包括内存。因此,您创建了一个测试用户,将他们的内存使用限制在足以启动您的程序的范围内,然后看着它死掉:)
例子:
ulimit -m 64
将内存限制设置为 64kb。
【讨论】:
【参考方案2】:创建您自己的 malloc 包装器,它将随机返回 null 而不是有效指针。好吧,或者如果你想进行单元测试,它会一直失败。
【讨论】:
还有calloc
、realloc
、strdup
,以及代码使用的任何其他内存分配函数。而且你会想要一种在构建发布时关闭此功能的方法。【参考方案3】:
在过度使用内存的操作系统(例如 Linux 或 Windows)上,根本不可能处理内存不足错误。 malloc 可能会返回一个有效的指针,稍后,当您尝试取消引用它时,您的操作系统可能会确定您内存不足并终止该进程。
http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/ 是一篇很好的文章。
【讨论】:
这种行为最近给我的项目造成了严重的痛苦。 man malloc 并在 BUGS 标题下查看。 echo /proc/sys/vm/overcommit_memory 如果为 2 则 overcommit 关闭。 这个答案是错误的。过度使用很容易被禁用,而其他因素,如ulimit
或整个虚拟地址空间的耗尽也可能导致分配失败。
如果您禁用过度使用,那么您将不再处于过度使用内存的系统上;我的评论是关于确实过度使用内存的系统。在许多情况下,程序员无法禁用过度使用。您指向 oom_pardon 讨论的链接非常有趣。 :)【参考方案4】:
您可以编写自己的模拟库,使用与您的第 3 方库相同的界面来代替它。您还可以使用 LD_PRELOAD 覆盖 3rd 方库的选定函数。
【讨论】:
【参考方案5】:我可以给出一个 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>
等等
您可以使用它来检测泄漏、随机分配失败等。
【讨论】:
malloc 宏无助于模拟 3rd 方库中的故障 - 它们已经通过调用原始 malloc 进行编译。不过,LD_PRELOAD 会有所帮助。【参考方案6】:此外,您应该使用Valgrind 对其进行测试并获得有关您程序的内存行为的真正有用的报告
【讨论】:
子工具叫做massif。 massif 是一个堆分析器。它测量您的程序使用了多少堆内存。它将生成一个日志和一个后记 (.ps) 图表。【参考方案7】:您可以在头文件中设置一个定义,以便在使用 malloc 时返回 NULL:
通常 malloc 将通过以下方式受到保护:
if ((int *x = malloc(sizeof(int))) == NULL)
return NULL;
所以你使用定义来强制返回 NULL;伪代码示例:
# define malloc(X) NULL
并检查您是否遇到段错误
【讨论】:
【参考方案8】:你想要 bash 中的 ulimit 命令。尝试
help ulimit在 bash shell 提示符下。
【讨论】:
我不是西部最快的枪。甚至 esat 也会出现。【参考方案9】:(作为之前一些答案的补充)
查看“Electric Fence”以获取可以与可执行文件一起使用的 malloc 拦截库的示例(例如,使用 LD_PRELOAD 技巧)。
一旦你拦截了 malloc,你可以使用任何你想触发失败的东西。随机触发的故障将是对系统各个部分的良好压力测试。您还可以根据请求的内存量修改失败概率。
顺便说一句,你的想法很有趣,显然我想对我的一些代码做一些事情......
【讨论】:
【参考方案10】:您可能想查看一些面向恢复的计算站点,例如Berkeley/Stanford ROC group。我之前听过其中一些人的谈话,他们使用代码在 C 运行时中随机注入错误。在他们的页面底部有一个指向他们的 FIT 工具的链接。
【讨论】:
工具名好像是FIG,不是FIT。【参考方案11】:看看the way sqlite3 does this。他们执行广泛的单元测试,包括内存不足测试。
您可能还想查看their page on malloc,尤其是Section 4.0。
【讨论】:
以上是关于如何模拟内存分配错误的主要内容,如果未能解决你的问题,请参考以下文章
错误:无法分配内存:尝试在 2560x1600 xhdpi 的 eclipse 模拟器中运行我的应用程序时出现 1455
内存分配“错误:无法分配大小为 75.1 Mb 的向量”[重复]