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