malloc中的电围栏段错误

时间:2012-11-28 22:04:13

标签: debugging gdb segmentation-fault electric-fence

我有一个相当复杂的程序,它会进行大量的内存分配,而今天出乎意料的是,它开始以一种奇怪的方式进行segfaulting,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,否则后面跟踪与上面相同。

除了fence之外,我没有明确链接任何其他库。

更新:我发现有几个地方暗示消息:“mprotect()失败:无法分配内存”意味着机器上没有足够的内存。但我没有看到“无法分配内存”的部分,ps说我只使用了15%的内存。如此小的分配(4k + 32)这真的是问题吗?

1 个答案:

答案 0 :(得分:11)

我在同样的问题上浪费了几个小时。 事实证明,它与设置有关 的/ proc / SYS / VM / max_map_count

从内核文档: “此文件包含进程可能具有的最大内存映射区域数。内存映射区域用作调用malloc的副作用,直接由mmap和mprotect,以及加载共享库时。

虽然大多数应用程序只需要不到一千张地图,但某些程序(尤其是malloc调试程序)可能会消耗大量的程序,例如,每次分配最多可以使用一到两个地图。“

所以你可以'捕捉'那个文件以查看它的设置,然后你可以'回显'一个更大的数字。像这样:echo 165535&gt;的/ proc / SYS / VM / max_map_count

对我而言,这让电围栏能够超越之前的状态,开始发现真正的虫子。