Note that there are some explanatory texts on larger screens.

plurals
  1. POSystemStackError at the rack level in Ruby 1.9.2, not 1.8.7
    text
    copied!<p>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: <strong>Why?</strong></p> <p>Basically, I was seeing a <code>SystemStackError</code> 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 <code>SystemStackError</code> when the database was hit. So I figured it was something lazy loading.</p> <p>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.</p> <p>Fast-forward too many hours, and I tracked down the traceback to a loop in Rails (<a href="https://gist.github.com/2933177" rel="noreferrer">full gist</a>):</p> <pre><code>/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' ... </code></pre> <p>What we see here is the system cycling from <code>metal.rb</code> to <code>url_for.rb</code> to <code>layouts.rb</code> to <code>rendering.rb</code> to <code>metal.rb</code> to <code>url_for.rb</code>, etc</p> <p>After considerable effort, I tracked this down to the following line at the top of a model file (<a href="https://github.com/mettadore/infinite_loop/blob/master/app/models/widget.rb#L1" rel="noreferrer">like so</a>):</p> <pre><code>include ActionView::Helpers::UrlHelpers </code></pre> <p>Note, this is not inside the class, it is at the module level.</p> <p>The interesting thing is that <strong>this works in Ruby 1.8.7 but causes a <code>SystemStackError</code> in Ruby 1.9.2.</strong></p> <p>I have created a <a href="https://github.com/mettadore/infinite_loop" rel="noreferrer">Github repository illustrating this behavior</a>.</p> <p>If you grab this repository, and run the <code>ruby18</code> branch, you can load a page. If you run the <code>ruby19</code> 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).</p> <p>So, does anyone know why?</p> <p>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 <em>caused</em> 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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload