Ruby 1.9.2(而非1.8.7)中机架级的SystemStackError [英] SystemStackError at the rack level in Ruby 1.9.2, not 1.8.7
问题描述
我进入了旧版代码库,将其从Rails 2.4/Ruby 1.8.7升级到Rails 3.1/Ruby 1.9.2.这样做的时候,我发现了一个非常有趣的问题,花了3天的时间才能弄清楚.我想把它放到这里,以便给其他人看到问题的Google果汁,并问一个问题:为什么?
I was brought in on a legacy codebase to upgrade it from Rails 2.4/Ruby 1.8.7 to Rails 3.1/Ruby 1.9.2. While doing this, I found a very interesting problem that took 3 days to try to figure out. I wanted to drop it here both to give it some Google juice for someone else seeing the problem, and to ask the question: Why?
基本上,运行我的应用程序时,在机架级别上看到了SystemStackError
.在导致错误之前,我无法获得任何请求,并且由于从未触摸过我的代码,因此无法调试它.在开发模式下,我将能够看到很多站点,然后在命中数据库时突然得到SystemStackError
.所以我认为这是个懒惰的加载.
Basically, I was seeing a SystemStackError
at the Rack level when running my app. I couldn't get any requests through before the error was caused, and couldn't debug it because my code was never touched. In Development mode, I would be able to see much of the site, then would suddenly get the SystemStackError
when the database was hit. So I figured it was something lazy loading.
切换到生产模式,并且在第一个请求上发生异常.服务器正常启动,但是没有任何请求通过它,并且我的代码没有被触及.
Switch to production mode, and the exception happens on the first request. The server starts normally, but no requests make it through, and my code wasn't touched.
前馈时间过多,我追踪了回溯到Rails中的一个循环(完整摘要):
Fast-forward too many hours, and I tracked down the traceback to a loop in Rails (full gist):
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:102:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `new'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `block in action'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `dispatch'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:35:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:152:in `block in call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:96:in `block in recognize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:68:in `optimized_each'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:95:in `recognize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:141:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:538:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/omniauth-1.1.0/lib/omniauth/builder.rb:48:in `call'
...
我们在这里看到的是系统从metal.rb
到url_for.rb
到layouts.rb
到rendering.rb
到metal.rb
到url_for.rb
的循环,等等
What we see here is the system cycling from metal.rb
to url_for.rb
to layouts.rb
to rendering.rb
to metal.rb
to url_for.rb
, etc
After considerable effort, I tracked this down to the following line at the top of a model file (like so):
include ActionView::Helpers::UrlHelpers
注意,这不在类内部,而是在模块级别.
Note, this is not inside the class, it is at the module level.
有趣的是,这在Ruby 1.8.7中有效,但在Ruby 1.9.2中导致SystemStackError
.
The interesting thing is that this works in Ruby 1.8.7 but causes a SystemStackError
in Ruby 1.9.2.
我已经创建了一个 Github存储库,说明了此行为.
如果获取此存储库并运行ruby18
分支,则可以加载页面.如果运行ruby19
分支,则在任何请求(任何加载了Widget的请求,在生产环境中运行它都不会延迟加载)时都会出现SystemStackError.
If you grab this repository, and run the ruby18
branch, you can load a page. If you run the ruby19
branch, you get a SystemStackError on any request (any request where Widget is loaded, run it in production and it won't be lazy loaded).
那么,有人知道为什么吗?
So, does anyone know why?
我的意思是,我想它与Ruby 1.9加载模块的方式有关,因为它似乎不是Rails核心引起的问题.我主要关心的问题是,这是否只是代码库中的懒惰编程实践引起的深奥问题,还是在Ruby或Rails中是更深层问题的指针.
I mean, I imagine it has something to do with the way Ruby 1.9 loads modules, since it doesn't seem to be a problem caused by the Rails core. My main concern is a question of whether this is just an esoteric issue caused by lazy programming practices in the codebase, or if it is a pointer to a deeper problem, either in Ruby or Rails.
推荐答案
这看起来像错误3144 ,表示直接引用帮助程序.
This looks like Bug 3144, saying to reference the helper directly.
Rails.application.routes.url_helpers
这篇关于Ruby 1.9.2(而非1.8.7)中机架级的SystemStackError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!