Ruby 1.9.2(而非1.8.7)中机架级的SystemStackError [英] SystemStackError at the rack level in Ruby 1.9.2, not 1.8.7

查看:70
本文介绍了Ruby 1.9.2(而非1.8.7)中机架级的SystemStackError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我进入了旧版代码库,将其从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.rburl_for.rblayouts.rbrendering.rbmetal.rburl_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆