1

我在 Heroku Bamboo MRI (Ruby) 1.9.2 上的 Rails 3.0.9 上运行 Spree 0-60-stable

2011 年 12 月 3 日星期六或前后的某个时间,我开始在控制器中收到“SystemStackError(堆栈级别太深)”消息,这些消息之前没有引发该错误。自 11 月 28 日以来,我没有重新编译过 slug。我首先尝试重新启动我的网络进程,但无济于事。从那以后,我做了一个名义上的更改(我的 Gemfile 中的一行空格),所以我可以重新编译并推动它。不用找了。我仍然收到错误消息。我查看了我可能迁移到的可用堆栈,但除了我在竹核磁共振 1.9.2 上的堆栈之外,没有其他堆栈明确支持我的应用程序正在使用的 ruby​​ 版本。

错误(根据 Heroku 支持)是:

ActionView::Template::Error(堆栈级别太深)

他们接着说,“这意味着您的模板中有一些东西正在进行可能的递归调用。虽然缺少代码更改可能表明我们有一些奇怪的行为,但您的数据库中也有可能发生了一些变化或者某些基于时间的东西会导致行为发生变化。在任何一种情况下,完整的堆栈跟踪都会有所帮助。您是否使用 Airbrake 或 Exceptional 来捕获此错误并确定源?

我已经添加了Airbrake (Hoptoad) 和Exceptional来检查它们在堆栈跟踪方面可能显示的内容。两者都提供相同的文件/行参考,但没有更多信息:

.bundle/gems/ruby/1.9.1/gems/actionpack-3.0.9/lib/action_controller/metal/rescue.rb:19

这似乎不是很有帮助,因为它是救援本身,而不是实际触发它的任何代码行,我只有最外层的上下文。我在几个地方看到了同样的错误:

所以这是我的问题总结:

  1. 我没有更改我的代码,并且问题“突然出现”。
  2. 如果是数据更改,例如管理员中的设置,那是什么?
  3. 由于缺乏完整的堆栈跟踪,故障排除变得困难。

最后,我的问题:

可以在没有完整堆栈跟踪的情况下识别“SystemStackError:堆栈级别太深”的起源吗?

非常感谢您的任何帮助。

4

2 回答 2

2

在这种情况下,我会使用“printf 调试”。在控制器和模板代码的各个点添加log.info "got to here 1"(2, 3 ,4 etc)。

然后重现错误。然后检查日志并查看哪些语句已记录/未记录 - 因此您访问代码的哪些部分以及是否有任何部分无休止地重复......

并且您至少已将问题范围缩小到代码的哪一部分。

于 2011-12-06T19:56:22.940 回答
2

SystemStackError通常是由一些直接或间接调用自身的递归方法引起的。这要么是由创建无限递归的错误引起的,要么是由递归发生的某些操作引起的,因此仅适用于有限大小的数据。

例子

class Array
  def size
    return 0 if self.empty?
    1+self[1..-1].size
  end
end

理论上这是大小的正确实现,但它的堆栈大小与数组大小成线性增长。在我的系统上,这个实现失败,SystemStackError大于Arrays8714。

写入puts你的代码

如果您怀疑哪些方法可能导致此问题,puts请在方法中添加一些调试输出。如果您看到某个方法的大量输出,您可以假设错误在该方法附近的某个地方。

跟踪所有方法

使用 ruby​​s 内置挂钩来跟踪所有方法创建。然后自动修改每个新创建的方法以生成一些调试输出。使用所有这些调试信息,您的代码运行速度会非常慢,但您可能会在跟踪中看到递归的原因。

于 2011-12-06T20:01:28.110 回答