2012-10-30 4 views
9

EDIT: (GELÖST) es tatsächlich wahrscheinlich wegen einer Endlosschleife angehoben wurdeRuby-Stack-Ebene zu tief Ausnahme nicht rekursive Endlosschleife

Ich war Codierung und nach einem Verfahren das Hinzufügen ich das bekam:

[email protected]_computer:/media/ECC3-C3B0/Prog/mts/src/mts$ rake test --trace 
** Invoke test (first_time) 
** Execute test 
/home/user_name/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36: stack level too deep (SystemStackError) 
rake aborted! 
Command failed with status (1): [/home/user_name/.rvm/rubies/ruby-1.9.3-p19...] 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils.rb:53:in `block in create_shell_runner' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `call' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `sh' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `sh' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils.rb:82:in `ruby' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `ruby' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/testtask.rb:99:in `block (2 levels) in define' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:60:in `verbose' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/testtask.rb:98:in `block in define' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain' 
/home/user_name/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:116:in `invoke_task' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block (2 levels) in top_level' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `each' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block in top_level' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:88:in `top_level' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:66:in `block in run' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run' 
/home/user_name/.rvm/gems/[email protected]/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>' 
/home/user_name/.rvm/gems/[email protected]/bin/rake:19:in `load' 
/home/user_name/.rvm/gems/[email protected]/bin/rake:19:in `<main>' 
/home/user_name/.rvm/gems/ruby-1.9.3-p194/bin/ruby_noexec_wrapper:14:in `eval' 
/home/user_name/.rvm/gems/ruby-1.9.3-p194/bin/ruby_noexec_wrapper:14:in `<main>' 
Tasks: TOP => test 

Ich bin ziemlich sicher, dass es keine unendliche rekursive Schleife beteiligt ist.

Der Code ist für jetzt irgendwie gemifiziert, aber ich habe auch den Fehler, die Ruby-Datei direkt ausgeführt.

Vielen Dank für jede Hilfe, wie man (einige Informationen zu bekommen, einige Tests laufen zu lassen) das Problem zu beheben, wenn möglich, ohne dass die ganze Sache neu zu schreiben ...

Umwelt:

  • Rubin 1.9.3p194/Schienen 3.2.8, über rvm installiert
  • das Programm in diesem Stadium nur Schienen String inflexions Funktionen
  • OS verwendet: linux Kubuntu i386
  • Speicher 4GO
  • 'ulimit -s': 8192 (Stack-Größe in kB)

Was erfolglos versuchte ich:

  • entfernt, um den Teil des Codes, wo die Ausnahme ursprünglich erhoben wurde, aber es war immer noch angehoben ein kleines bisschen später zur Laufzeit
  • Set-Stack-Größe mit der Befehlszeile 'ulimit -s 20000', 'ulimit -s unbegrenzt'. Gleiche Fehler, anscheinend an der gleichen Stelle (die ich die Stack-Größe denke, macht nicht wirklich geändert)
  • degradiert/rails3.1.3 ruby1.9.2, bekam die gleiche Meldung
  • gleiche Fehler unter Windows

Anwendungskontext:

Ich schreibe eine Anwendung, die stark Rubin Mixins verwendet.

Außerdem habe ich eine Reihe von Klassen erstellt, die Mixins generieren (Instanz-/Klassenmethoden-Module, die von anderen Klassen enthalten sein sollen).

Also alles in allem am Ende habe ich ziemlich viele generierte benannte Module mit einigen benutzerdefinierten generierten Code und Klassen mit vielen Vorfahren.

Aber das sollte mich schließlich ein wenig Schmerz in der as $ sparen, wenn ich das Programm schreibe, das oben auf dieser Lib sitzt (das ist der Plan sowieso).

Ressourcen I verwendet:

EDIT: Bis ein Code für die Vorführung/Testen zur Verfügung steht, lassen Sie uns abstrakt meine Frage nach unten zu diesem: Gibt es andere Fälle, die die Stapelebene zu tief Ausnahme, neben dem klassischen Programmausführung-Baum-ist-zu-tief-Szenario (das Überstreichen der Finger, es ist klar und bedeutet einige Ding...) ?

+0

Sehr guter Stil und Formatierung. –

+7

Was ist der Code? Schwer zu helfen, wenn du keinen Code zeigst. – vgoff

+1

Sie können rekursiv die gleiche Methode ohne Abbruch aufrufen. Ein Bericht von Profiler könnte hilfreich sein https://github.com/rdp/ruby-prof – Tombart

Antwort

3

Gibt es andere Fälle, die Stapelebene zu tief Ausnahme neben dem klassischen Programm-Ausführung-Baum-ist-zu-tief-Szenario?

Ja. Da der Stapel nicht in der Tiefe gemessen wird, aber in Bytes, auf dem Stapel gespeichert etwas wird es früher aufzufüllen:

def recurse(depth=0) 
    recurse depth+1 
rescue SystemStackError 
    depth 
end 
=> nil 
recurse 
=> 8717 

def recurse(depth=0) 
    a,b,c = 1,2,3 
    recurse depth+1 
rescue SystemStackError 
    depth 
end 
=> nil 
recurse 
=> 7264 

def recurse(depth=0) 
    a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z = *(0..25) 
    recurse depth+1 
rescue SystemStackError 
    depth 
end 
=> nil 
recurse 
=> 3187 

In diesem Beispiel wird eine Funktion mit nur einer Variable kann tief mehr tausend Anrufe gehen, bevor ein Fehler, und das Hinzufügen von drei weiteren Variablen tut sehr wenig; Wenn Sie jedoch 26 weitere Variablen hinzufügen, wird die Stapelgröße auf einen Wert erhöht, bei dem nur etwa 3000 Ebenen verfügbar sind.

Dies hängt natürlich etwas von der Ruby-Implementierung und dem System ab, auf dem es läuft. Aber ich glaube, es wird immer als eine allgemeine Regel gelten.

Dennoch denke ich, Rekursion ist wahrscheinlich Ihr Problem, da die Anzahl der Variablen erforderlich ist, um dies bei kleinen Aufrufkettenlängen passieren zu lassen, ist immens.

+1

oops. einen Fehler gemacht, der die Anrufkette kürzer als zuvor erscheinen ließ. korrigiert. –

+0

Vielen Dank für die Erklärung, ich dachte, initialisierte Variablen wurden während der Ausführung irgendwo anders gespeichert. Sie haben Recht (und alle anderen vor Ihnen), ich habe wahrscheinlich ein bisschen zu viel mit Neudefinitionen von Kernklassen zu tun gehabt, daher konnte ich die Ursache des Fehlers nicht erkennen. Problem gelöst (für jetzt) –