我正在使用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
出现在很多问题中?堆栈机制有什么不妥之处,还是我需要以某种方式为平台更改代码?
答案 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
让它成为永久性的。)