Debugging malloc的电气围栏故障

Debugging malloc的电气围栏故障,debugging,gdb,segmentation-fault,electric-fence,Debugging,Gdb,Segmentation Fault,Electric Fence,我有一个相当复杂的程序,它执行大量的内存分配,而今天出乎意料的是,它开始以一种奇怪的方式进行分段故障,gdb无法确定它的位置。我怀疑某个地方的内存被破坏了,于是把它和电子围栏联系起来,但我对它告诉我的东西感到困惑: ElectricFence Exiting: mprotect() failed: Program received signal SIGSEGV, Segmentation fault.

我有一个相当复杂的程序,它执行大量的内存分配,而今天出乎意料的是,它开始以一种奇怪的方式进行分段故障,gdb无法确定它的位置。我怀疑某个地方的内存被破坏了,于是把它和电子围栏联系起来,但我对它告诉我的东西感到困惑:

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>
最后两次完全没有效果

第一个更改了堆栈帧的部分,它们位于我的程序中(当malloc被致命调用时,在我的程序中执行),但在输入malloc后,它们具有相同的帧

第二个改变了一点;除了崩溃发生在我的程序中的另一个地方之外,它还发生在对realloc而不是malloc的调用中,尽管realloc直接调用malloc,否则返回跟踪与上面相同

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


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

我只是在同一个问题上浪费了几个小时。 事实证明,这与中的设置有关 /进程/系统/虚拟机/最大映射计数

从内核文档中: 此文件包含一个进程可能拥有的最大内存映射区域数。内存映射区域被mmap和mprotect直接用作调用malloc的副作用,并且在加载共享库时也是如此

虽然大多数应用程序需要不到1000个映射,但某些程序,特别是malloc调试器,可能会消耗大量映射,例如,每次分配最多一到两个映射。”

因此,您可以“cat”该文件以查看它设置为什么,然后您可以在其中“echo”一个更大的数字。像这样:echo 165535>/proc/sys/vm/max\u map\u count


对我来说,这使得电动围栏能够通过它以前的位置,并开始发现真正的虫子。

电动围栏有标签吗?找不到一个…静态链接您的程序并确保您的所有代码,并且libefence已使用
-g
编译,然后向我们展示更多您程序中的第一帧(#6)以及我的系统电子围栏上libefence(#5)中的第一帧是Debian包(似乎不可用-g),因此,如果我真的需要调试符号,则需要一些时间才能完成。我尝试过静态链接;我再也看不到启动时的电子围栏信息,也看不到崩溃信息,好像它已经不在了。
EF_PROTECT_FREE=1
EF_PROTECT_BELOW=1
EF_ALIGNMENT=64
EF_ALIGNMENT=4096