malloc中的电子围栏段错误
Posted
技术标签:
【中文标题】malloc中的电子围栏段错误【英文标题】:electric-fence segfaults in malloc 【发布时间】:2012-11-28 22:04:12 【问题描述】:我有一个相当复杂的程序,它会分配大量内存,但今天令人惊讶的是,它开始以一种奇怪的方式出现段错误,而 gdb 无法确定其位置。怀疑某处内存损坏,我将它与 Electric Fence 联系起来,但我对它告诉我的内容感到困惑:
ElectricFence Exiting: mprotect() failed:
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/i386/i686/multiarch/strlen.S:99
99 ../sysdeps/i386/i686/multiarch/strlen.S: No such file or directory.
in ../sysdeps/i386/i686/multiarch/strlen.S
#0 __strlen_sse2 () at ../sysdeps/i386/i686/multiarch/strlen.S:99
#1 0xb7fd6f2d in ?? () from /usr/lib/libefence.so.0
#2 0xb7fd6fc2 in EF_Exit () from /usr/lib/libefence.so.0
#3 0xb7fd6b48 in ?? () from /usr/lib/libefence.so.0
#4 0xb7fd66c9 in memalign () from /usr/lib/libefence.so.0
#5 0xb7fd68ed in malloc () from /usr/lib/libefence.so.0
#6 <and above are frames in my program>
我正在调用值为 36 的 malloc,所以我很确定这应该不是问题。
我不明白的是,我什至有可能在 malloc 中破坏堆。在阅读手册页多一点时,似乎我正在写入一个空闲页面,或者我正在承保一个缓冲区。所以,我尝试了以下环境变量,一起和单独使用:
EF_PROTECT_FREE=1
EF_PROTECT_BELOW=1
EF_ALIGNMENT=64
EF_ALIGNMENT=4096
最后两个完全没有效果。
第一个更改了我程序中的堆栈帧部分(当 malloc 被致命调用时,我的程序正在执行该部分),但输入 malloc 后具有相同的帧。
第二个改变了一点;除了在我的程序的不同地方发生崩溃之外,它还发生在对 realloc 而不是 malloc 的调用中,尽管 realloc 是直接调用 malloc ,否则回溯与上述相同。
我没有明确链接到除栅栏之外的任何其他库。
更新:我发现几个地方提示消息:“ mprotect() failed: Cannot allocate memory” 意味着机器上没有足够的内存。但我没有看到“无法分配内存”部分,ps 说我只使用了 15% 的内存。如此小的分配 (4k+32) 真的会是问题吗?
【问题讨论】:
电围栏有标签吗?找不到... 静态链接您的程序并确保您的所有代码,和 libefence 已使用-g
编译,然后向我们展示您程序中第一帧的更多内容(#6上面),以及 libefence 中的第一帧(上面的#5)
在我的系统电栅栏上有一个 Debian 软件包(似乎不可用 -g),所以如果我真的需要调试符号,需要一些时间才能完成。我确实尝试过静态链接;我在启动时不再看到 Electric Fence 消息,它也没有给出崩溃消息,就好像它不再存在一样。
【参考方案1】:
我只是在同一个问题上浪费了几个小时。 原来是和里面的设置有关 /proc/sys/vm/max_map_count
来自内核文档: "此文件包含一个进程可能拥有的最大内存映射区域数。内存映射区域用作调用 malloc 的副作用,直接由 mmap 和 mprotect 调用,也可在加载共享库时使用。
虽然大多数应用程序需要少于一千个映射,但某些程序,尤其是 malloc 调试器,可能会消耗大量映射,例如,每次分配最多一到两个映射。”
因此,您可以“cat”该文件以查看它的设置,然后您可以“回显”一个更大的数字。像这样: echo 165535 > /proc/sys/vm/max_map_count
对我来说,这让电围栏可以超越原来的位置,并开始发现真正的错误。
【讨论】:
以上是关于malloc中的电子围栏段错误的主要内容,如果未能解决你的问题,请参考以下文章
为啥在将 malloc() 的指针分配给 char* 时会出现段错误?