[ruby-list:50636] Ruby 2.4.3 で発生しない SystemStackError が Ruby 2.5.0 で発生する理由が分かりません
From:
鈴木将高 <koshigoeb@...>
Date:
2017-12-30 02:03:03 UTC
List:
ruby-list #50636
鈴木と申します。
Alpine Linux 3.7 にて、Ruby 2.4.3 では発生しなかった SystemStackError が
Ruby 2.5.0 で発生する様になりました。これは、実行(コンパイル)環境に依存
する問題だと考えたら良いでしょうか?(スレッドスタックサイズ?)
単純な再帰(def f; f; end; f)では深さに違いがありませんが、検証のために無
理矢理書いた以下の様なコードだと例外発生時の深さが大きく違います。
この深さが大きく異なる理由が分かりません。
# test.rb
n = 100000
res = {}
1.upto(n).to_a.inject(res) do |r, i|
r[i] = {}
end
def f(x)
x.each_value { |v| f(v) }
end
f(res)
例えば、Docker Hub の Docker イメージ ruby:2.5.0-alpine3.7 を使うと
137 levels で止まります。
% docker container run -v (pwd):/mnt/my --rm -it ruby:2.5.0-alpine3.7
ruby -v /mnt/my/test.rb
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux-musl]
Traceback (most recent call last):
149: from /mnt/my/test.rb:11:in `<main>'
148: from /mnt/my/test.rb:8:in `f'
147: from /mnt/my/test.rb:8:in `each_value'
146: from /mnt/my/test.rb:8:in `block in f'
145: from /mnt/my/test.rb:8:in `f'
144: from /mnt/my/test.rb:8:in `each_value'
143: from /mnt/my/test.rb:8:in `block in f'
142: from /mnt/my/test.rb:8:in `f'
... 137 levels...
4: from /mnt/my/test.rb:8:in `f'
3: from /mnt/my/test.rb:8:in `each_value'
2: from /mnt/my/test.rb:8:in `block in f'
1: from /mnt/my/test.rb:8:in `f'
/mnt/my/test.rb:8:in `each_value': stack level too deep
(SystemStackError)
一方で、Docker Hub の Docker イメージ ruby:2.4.3-alpine3.7 を使うと
10067 levels で止まります。
(ruby:2.5.0-alpine3.7 と ruby:2.4.3-alpine3.7 の違いは Ruby のバージョン指定のみ)
% docker container run -v (pwd):/mnt/my --rm -it ruby:2.4.3-alpine3.7
ruby -v /mnt/my/test.rb
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux-musl]
/mnt/my/test.rb:8:in `each_value': stack level too deep
(SystemStackError)
from /mnt/my/test.rb:8:in `f'
from /mnt/my/test.rb:8:in `block in f'
from /mnt/my/test.rb:8:in `each_value'
from /mnt/my/test.rb:8:in `f'
from /mnt/my/test.rb:8:in `block in f'
from /mnt/my/test.rb:8:in `each_value'
from /mnt/my/test.rb:8:in `f'
from /mnt/my/test.rb:8:in `block in f'
... 10067 levels...
from /mnt/my/test.rb:8:in `block in f'
from /mnt/my/test.rb:8:in `each_value'
from /mnt/my/test.rb:8:in `f'
from /mnt/my/test.rb:11:in `<main>'
また、Docker Hub の Docker イメージ ruby:2.5.0-stretch を使うと
9866 levels で止まりました。
% docker container run -v (pwd):/mnt/my --rm -it ruby:2.5.0-stretch
ruby -v /mnt/my/test.rb
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
Traceback (most recent call last):
9878: from /mnt/my/test.rb:11:in `<main>'
9877: from /mnt/my/test.rb:8:in `f'
9876: from /mnt/my/test.rb:8:in `each_value'
9875: from /mnt/my/test.rb:8:in `block in f'
9874: from /mnt/my/test.rb:8:in `f'
9873: from /mnt/my/test.rb:8:in `each_value'
9872: from /mnt/my/test.rb:8:in `block in f'
9871: from /mnt/my/test.rb:8:in `f'
... 9866 levels...
4: from /mnt/my/test.rb:8:in `f'
3: from /mnt/my/test.rb:8:in `each_value'
2: from /mnt/my/test.rb:8:in `block in f'
1: from /mnt/my/test.rb:8:in `f'
/mnt/my/test.rb:8:in `each_value': stack level too deep
(SystemStackError)