10

編集:(解決済み)実際には、無限ループのために発生した可能性があります

私はコーディングしていて、メソッドを追加した後、これを得ました:

user_name@the_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/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils.rb:53:in `block in create_shell_runner'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `call'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `sh'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `sh'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils.rb:82:in `ruby'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `ruby'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/testtask.rb:99:in `block (2 levels) in define'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:60:in `verbose'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/testtask.rb:98:in `block in define'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/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/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:116:in `invoke_task'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block (2 levels) in top_level'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `each'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block in top_level'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:88:in `top_level'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:66:in `block in run'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/bin/rake:19:in `load'
/home/user_name/.rvm/gems/ruby-1.9.3-p194@global/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

無限再帰ループが含まれていないことは確かです。

コードは今のところどういうわけかgem化されていますが、Rubyファイルを直接実行するとエラーも発生しました。

可能であれば、すべてを書き直すことなく問題を修正する方法(情報を取得し、いくつかのテストを実行する)についての助けをありがとう...

環境 :

  • ruby 1.9.3p194 / rails 3.2.8、rvm経由でインストール
  • この段階のプログラムは、Rails 文字列の屈折関数のみを使用します。
  • OS:linux kubuntu i386
  • メモリー4GO
  • 'ulimit -s' : 8192 (kB 単位のスタック サイズ)

私が失敗したこと:

  • 例外が最初に発生したコードのチャンクを削除しましたが、実行時に少し遅れてまだ発生していました
  • コマンド ライン 'ulimit -s 20000'、'ulimit -s unlimited' でスタック サイズを設定します。明らかに同じ場所にある同じエラー(スタックサイズが実際には変更されていないと思います)
  • ruby1.9.2 / rails3.1.3 にダウングレードしても同じメッセージが出る
  • Windows での同じエラー

アプリケーション コンテキスト:

ruby ミックスインを多用するアプリケーションを作成しています。

さらに、ミックスインを生成する一連のクラスを作成しました (他のクラスに含まれるインスタンス / クラス メソッド モジュール)。

したがって、最終的には、いくつかのカスタム生成コードを含むかなりの量の名前付きモジュールと、多くの祖先を持つクラスが生成されます。

しかし、最終的には、この lib の上にあるプログラムを作成するときに、as$ のかなりの負担が軽減されるはずです (いずれにせよ、それが計画です)。

私が使用したリソース:

編集: いくつかのコードが表示/テストに使用できるようになるまで、私の質問をこれに抽象化しましょう: 古典的なプログラム実行ツリーが深すぎるシナリオ (交差する指は明らかで、何かを意味します...) ?

4

1 に答える 1

4

従来のprogram-execution-tree-is-too-deepシナリオ以外に、スタックレベルを上げる例外が深すぎる場合はありますか?

はい。スタックは深さではなくバイト単位で測定されるため、スタックに格納されているものはすべて、より早くいっぱいになります。

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

この例では、変数が1つしかない関数は、失敗する前に数千回の呼び出しを行うことができ、さらに3つの変数を追加してもほとんど効果がありません。ただし、さらに26個の変数を追加すると、スタックサイズが膨らみ、約3000レベルしか使用できなくなります。

もちろん、これはrubyの実装とそれが実行されているシステムに多少依存します。しかし、私はそれが原則として常に成り立つと信じています。

ただし、コールチェーンの長さが短い場合に再帰を発生させるために必要な変数の数は膨大であるため、再帰が問題になる可能性が高いと思います。

于 2012-12-14T21:34:14.313 に答える