4

似乎我总是在我的一个脚本上收到此错误:

/Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/ruby-prof-0.11.2/lib/ruby-prof/profile.rb:25: stack level too deep (SystemStackError)

有没有人遇到过这个错误?什么可能导致它,我能做些什么来防止它发生?

我使用命令运行我的 ruby​​-prof 脚本

ruby-prof --printer=graph --file=profile.txt scraper.rb -- "fall 2012"

编辑我在 Mac OS X 上,如果这很重要的话。不幸的是,这样做ulimit -s 64000似乎没有多大帮助。这是ulimit -a给出的:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 64000
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

编辑 2

Andrew Grimm 的解决方案可以很好地防止 ruby​​-prof 崩溃,但分析器似乎有其自身的问题,因为我看到一个进程所花费的总时间的百分比为 679.50%......

4

3 回答 3

6

一种解决方法是打开尾调用优化

以下是在 TCO 打开时工作但在 TCO 关闭时不起作用的示例。

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

def countUpTo(current, final)
  puts current
  return nil if current == final
  countUpTo(current+1, final)
end

countUpTo(1, 10_000)
于 2012-07-31T23:23:51.447 回答
3

堆栈级别太深通常意味着无限循环。如果您查看发生错误的 ruby​​-prof 代码,您会发现它是一种在调用堆栈中检测递归的方法。

试着查看你使用递归的代码(你的代码中有多少地方可以使用递归?),看看是否有一个条件会导致它永远不会触底?

这也可能意味着您的系统堆栈不足以处理您正在尝试做的事情。也许您正在递归处理大型数据集?您可以检查堆栈大小(unixy 系统):

$ ulimit -a

增加堆栈大小

$ ulimit -s 16384

你也可以考虑调整你的算法。看到这个堆栈溢出问题

我希望我不只是重新散列一个现有的问题......

于 2012-07-27T17:57:39.920 回答
2

Ruby-prof 中的百分比超过 100% 是一个已知错误,但现在应该修复。

于 2013-02-11T21:40:22.787 回答