我有一个系统堆栈错误,其原因很难找到,所以要按照这里的建议进行查找: 我添加了这个块:
module ApplicationHelper
set_trace_func proc {
|event, file, line, id, binding, classname|
if event == "call" && caller_locations.length > 500
fail "stack level too deep"
end
}
end
我添加了上面的块app/helpers/application_helper.rb
,不确定它是最好的地方。
问题:
添加此内容后,我的应用程序立即开始失败并显示以下错误:
#<LocalJumpError: unexpected return>
INFO -- : worker=0 spawning...
ERROR -- : reaped #<Process::Status: pid 1440 exit 1> worker=0
INFO -- : worker=0 spawned pid=1443
INFO -- : Refreshing Gem list
我做错了什么?
我把set_trace_func
放错地方了吗?
好的,一步一步。
我们这里有两个不同的例外:
1.- 系统堆栈错误:这可能是由于无限循环或非常大的堆栈。我们需要更多信息来调试它。选项:
-
懒惰选项:请粘贴您的回溯。
-
DIY选项:有一个交互式调试会话,我知道一个简单的方法来实现这一点。恕我直言,对于您尝试调试的内容来说,
set_func_trace
级别太低(无论这在 Ruby :p 中意味着什么(:- 将
pry
(https://github.com/pry/pry( 和pry-stack-explorer
(https://github.com/pry/pry-stack_explorer( 添加到项目中。 -
将以下内容添加到您的
ApplicationController
中。rescue_from SystemStackError do |exception| binding.pry end
-
启动您的服务器并复制您的错误。
-
进入控制台后,您可以使用
exception.backtrace
检查回溯,并使用pry-stack-explorer
提供的一些魔法来导航堆栈,它在内部使用binding.callers
。例如
show-stack
然后使用frame X
移动到所需的帧。在违规框架中,您可以检查所有行为和属性。
- 将
2.- LocalJumpError:这看起来像这样一行:fail "stack level too deep"
在你的set_trace_func
内部,正在引发一个RuntimeError
,StandardError
的儿子,这会影响先前在堆栈中定义的救援行为,很可能在ActiveSupport依赖加载机制中。
我无法重现这一点,但是如果您检查本地ActiveSupport安装,则很有可能在该特定版本中有提示。 例如 从你的壳里less $(bundle show activesupport)/lib/active_support/dependencies.rb
。
我将引用 ruby-doc.org:LocalJumpError 意味着在块调用中具有return
或在没有块的方法中产生。