C堆栈奇怪的行为

时间:2015-01-03 03:09:47

标签: c segmentation-fault stack

我正在使用Ubuntu 14.04上的Hope功能程序和gcc 4.8.2,并使用高递归函数来查找大量素数。但是,我得到了一个分段错误:0x000000000040e03f到达

cell=<error reading variable: Cannot access memory at address 0x7fffff7feff8> at runtime.c:250

访问地址0x7fffff7feff8时会发生分段错误。

到达例程正在做的是取消标记当前表达式可以访问的堆项(使用垃圾收集标记扫描)。堆栈非常深(100000多个调用),但没有堆栈溢出:

base_memory = 0x7ffff35a4010
top_string = 0x7ffff35a5260
BaseHeap = 0x7ffff35a5260
heap = 0x7ffff603a450
stack = 0x7ffff72da498
TopStack = 0x7ffff7584d60

从base_memory到TopStack的区域分配了malloc。

每当我收到段违规时,地址总是为0x7fffff7feff8,即使功能差异很大。

如果您使用Google地址0x7fffff7feff8,则会有相当多的条目违反此地址,但无法解决此问题。

我将代码检查到堆地址是否在堆范围内,但它从未失败。

我做了一个gdb

find 0x7ffff35a4010,0x7ffff7584d60,0x7fffff7feff8

并没有找到任何东西。

为什么地址0x7fffff7feff8出现在很多问题中?堆栈机制有什么不妥之处,还是我需要以某种方式为平台更改代码?

1 个答案:

答案 0 :(得分:4)

这看起来像x86-64系统上的堆栈溢出而没有地址空间布局随机化。如果堆栈开始于0x7ffffffff000,就像它们在这样的系统上一样,0x7fffff7feff8可疑地接近堆栈开头下方8 MB,这是Linux系统上常见的默认线程堆栈大小。

转储/proc/self/maps的内容并检查堆栈的开头是否与此匹配(它在底部列出),并检查ulimit -s以查看新进程获得的堆栈大小。如果/proc/self/maps列出0x7ffffffff000作为堆栈地址范围的末尾而ulimit -s打印8192,那么您所拥有的只是堆栈溢出。在这种情况下,快速修复将增加新进程(活动shell的子进程)的堆栈大小,如下所示:

ulimit -Ss size_in_kilobytes

这可能会达到可能会或可能不会施加的严格限制root。从长远来看,以较少过度的递归方式重写代码可能是个好主意。

此外,如果所有这些都回家,您应该启用ASLR(sysctl kernel.randomize_va_sapce=1。如果抱怨,您的系统急需升级。将kernel.randomize_va_space = 1写入/etc/sysctl.conf让它成为永久性的。)

相关问题