我有一个相当复杂的程序,它进行了大量的内存分配,今天令人惊讶的是,它以一种 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)真的会是问题吗?