【问题标题】:C stack odd behaviorC堆栈奇怪的行为
【发布时间】:2015-03-01 07:52:19
【问题描述】:

我在 Ubuntu 14.04 和 gcc 4.8.2 上使用 Hope 函数程序,并执行高度递归函数来查找大量素数。但是,我遇到了一个分段错误:0x000000000040e03f inreach

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

访问地址0x7fffff7feff8时出现分段错误。

reach 例程正在做的是取消标记当前表达式可以到达的堆项目(使用垃圾收集标记-清除)。堆栈很深(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 出现在这么多问题中?堆栈机制是否有问题,或者我需要以某种方式为平台更改代码?

【问题讨论】:

  • 代码在哪里>(顺便说一句,我喜欢寻找大质数,你需要得到更多!)
  • 我认为代码相当复杂。我要问的是存在某种模式或常见错误,因为错误地址 0x7fffff7feff8 在 google 上似乎出现了很多,并且使用 gdb 段违规没有意义。
  • valgrind 下运行程序可能会提示问题出在哪里。如果您已经这样做了,请跳过此评论 :)
  • 我可能会在明天尝试 valgrind。谢谢。

标签: c segmentation-fault stack


【解决方案1】:

这更像是在没有地址空间布局随机化的 x86-64 系统上的堆栈溢出。如果堆栈从0x7ffffffff000 开始,就像它们在此类系统上所做的那样,0x7fffff7feff8 可疑地接近堆栈开头以下 8 MB,这是 Linux 系统上常见的默认线程堆栈大小。

转储/proc/self/maps 的内容并检查堆栈的开头是否与此匹配(它列在底部),并检查ulimit -s 以查看新进程获得的堆栈大小。如果/proc/self/maps0x7ffffffff000 列为堆栈地址范围的末尾并且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 以使其永久化)。

【讨论】:

  • 你的分析是正确的。将 kernel.randomize_va_space = 1 写入 /etc/sysctl.conf 效果最大,但更改 ulimit -s 也有帮助。在函数式编程中,大多数事情都是通过递归完成的。您可以尝试使事物尾递归,因此堆栈大小不会变得那么大。我现在是一个快乐的露营者。
  • 更正:使用ASLR没有区别,但是改ulimit -s差别很大
  • 是的,这是有道理的。 ASLR 应该只改变堆栈的位置,而不是它的大小,并且代码将从不同的起点以相同的方式增长它。使用 ASLR,您应该会在 /proc/self/maps 中看到不同的堆栈范围,但是堆栈溢出应该发生在不同的地址。
猜你喜欢
  • 2010-10-14
  • 2013-05-28
  • 1970-01-01
  • 2012-06-14
  • 2021-11-01
  • 2023-03-21
  • 2015-08-04
  • 2012-02-14
  • 1970-01-01
相关资源
最近更新 更多