Sono stato inserito in un codebase legacy per aggiornarlo da Rails 2.4/Ruby 1.8.7 a Rails 3.1/Ruby 1.9.2. Mentre lo facevo, ho trovato un problema molto interessante che impiegava 3 giorni per cercare di capire. Ho voluto rilasciarlo qui sia per dargli un po 'di succo di Google per qualcun altro che ha visto il problema, e per porre la domanda: Perché?SystemStackError a livello di rack in Ruby 1.9.2, non 1.8.7
Fondamentalmente, stavo vedendo un SystemStackError
a livello di Rack durante l'esecuzione della mia app. Non è stato possibile ottenere alcuna richiesta prima che l'errore fosse causato e non è stato possibile eseguirne il debug perché il mio codice non è mai stato toccato. In modalità Sviluppo, sarei in grado di vedere gran parte del sito, quindi improvvisamente otterrei il SystemStackError
quando il database è stato colpito. Quindi ho pensato che fosse un caricamento pigro.
Passare alla modalità di produzione e l'eccezione si verifica alla prima richiesta. Il server si avvia normalmente, ma non è stata inoltrata alcuna richiesta e il mio codice non è stato toccato.
avanti veloce troppe ore, e ho rintracciato il traceback ad un anello in Rails (full gist):
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:102:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/[email protected]tream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `new'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `block in action'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `call'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `dispatch'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:35:in `call'
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:152:in `block in call'
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:96:in `block in recognize'
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:68:in `optimized_each'
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:95:in `recognize'
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:141:in `call'
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:538:in `call'
/Users/john/.rvm/gems/[email protected]/gems/omniauth-1.1.0/lib/omniauth/builder.rb:48:in `call'
...
Quello che vediamo qui è il ciclismo sistema da metal.rb
a url_for.rb
a layouts.rb
-rendering.rb
a metal.rb
a url_for.rb
, ecc
Dopo uno sforzo considerevole, ho rintracciato questo fino alla seguente riga nella parte superiore di un file di modello (like so):
012.351.include ActionView::Helpers::UrlHelpers
Nota, questo non è all'interno della classe, è a livello di modulo.
La cosa interessante è che funziona in Ruby 1.8.7 ma provoca un SystemStackError
in Ruby 1.9.2.
Ho creato un Github repository illustrating this behavior.
Se si acquisisce questo repository ed è in esecuzione il ramo ruby18
, è possibile caricare una pagina. Se si esegue il ramo ruby19
, si ottiene un errore SystemStackError su qualsiasi richiesta (qualsiasi richiesta in cui è caricato il Widget, la esegue in produzione e non sarà caricata pigro).
Quindi, qualcuno sa perché?
Voglio dire, immagino che abbia qualcosa a che fare con il modo in cui i moduli di Ruby 1.9 carica, dal momento che non sembra essere un problema causato dal nucleo Rails. La mia preoccupazione principale è la questione se si tratti solo di un problema esoterico causato da pratiche di programmazione pigra nel codebase o se si tratta di un puntatore a un problema più profondo, sia in Ruby che in Rails.
Ho lo stesso problema. Per aggiungere un po 'più di contesto, se lancio l'intera suite di test, visualizzo questo errore, ma se lancio un singolo test funziona senza intoppi. Qualche notizia sulla risoluzione? con la risoluzione – gicappa
per me era necessario rimuovere '' 'include ActionView :: Helpers :: UrlHelpers''' che stava causando il loop. Se non lo hai, il mio sospetto, senza sapere nulla del tuo codice, è che c'è un'altra cosa simile. – JohnMetta
Grazie ho scoperto che avevo un ActionView :: Helpers :: TagHelper incluso in un test. – gicappa