debugging - malloc 中的电子围栏段错误

标签 debugging gdb segmentation-fault electric-fence

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

最佳答案

我只是在同一个问题上浪费了几个小时。 原来是和里面的setting有关 /proc/sys/vm/max_map_count

来自内核文档: “此文件包含进程可能拥有的内存映射区域的最大数量。内存映射区域用作调用 malloc 的副作用,直接由 mmap 和 mprotect 调用,在加载共享库时也是如此。

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

因此您可以“搜索”该文件以查看它的设置,然后您可以“回显”一个更大的数字到其中。像这样: echo 165535 >/proc/sys/vm/max_map_count

对我来说,这让电围栏越过它之前的位置,并开始发现真正的错误。

关于debugging - malloc 中的电子围栏段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13615213/

相关文章:

C 编程 poll() 上的段错误

c++ - 插入 vector

在 Visual Studio Code 和 Delve 调试器中使用标签调试 Go

c# - 在当前调试器 session 下启动新进程

node.js - 如何调试 NodeJS 中的套接字挂起错误?

c - nm 输出和 gdb 中的函数地址不同

visual-studio - Visual Studio 监 window 口中的问号 (???) 表示什么?

assembly - 告诉 gdb 反汇编 "unknown"代码

eclipse - gdb 在 Eclipse 中失败

c++ - 对检索到的 vector 进行操作时出现段错误