Project

General

Profile

Actions

Bug #14387

open

Ruby 2.5 を Alpine Linux で実行すると比較的浅めで SystemStackError 例外になる

Added by koshigoe (Masataka SUZUKI) over 3 years ago. Updated over 1 year ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux-musl]
[ruby-dev:50421]
Tags:

Description

CircleCI で Alpine Linux を使って Ruby 2.5.0 で Rubocop を実行した時に遭遇した例外です(Ruby 2.4.3 では発生しませんでした)。

Ruby のバージョンによって、再帰が止められるまでの回数に大きな違いがあるのはなぜでしょうか?
これは、意図された挙動なのか、Ruby の変更によるものでは無く Alpine Linux 固有の問題なのか、教えていただく事は可能でしょうか?

Alpine Linux の Tread stack size が比較的小さい事で、Ruby 2.5.0 からこのような挙動になったのでしょうか?
https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size

再現

問題の再現のため、以下の様な再帰するコードを実行します。

# 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)

Ruby 2.4.3 で実行した場合、 10061 levels で例外があがりました。

% docker container run \
  -v (pwd):/mnt/my --rm \
  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:9:in `each_value': stack level too deep (SystemStackError)
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
         ... 10061 levels...
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:12:in `<main>'

一方で Ruby 2.5.0 で実行した場合、 134 level で例外があがりました。

% docker container run \
  -v (pwd):/mnt/my --rm \
  test/ruby:trunk-alpine3.7 \
  ruby -v /mnt/my/test.rb
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux-musl]
/mnt/my/test.rb:9:in `each_value': stack level too deep (SystemStackError)
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
         ... 134 levels...
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:12:in `<main>'

また、Ruby trunk で実行した場合は 2.5.0 同等の結果になりました。

ruby 2.6.0dev (2018-01-24 trunk 62017) [x86_64-linux-musl]
/mnt/my/test.rb:9:in `each_value': stack level too deep (SystemStackError)
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:9:in `block in f'
         ... 134 levels...
        from /mnt/my/test.rb:9:in `block in f'
        from /mnt/my/test.rb:9:in `each_value'
        from /mnt/my/test.rb:9:in `f'
        from /mnt/my/test.rb:12:in `<main>'

※ trunk の Docker イメージを作った際の Dockerfile は以下。
https://gist.github.com/koshigoe/509be02a3580cdfc7a2cc45a4e6e44c5


Files


Related issues

Related to Ruby master - Bug #13412: Infinite recursion with define_method may cause silent SEGV or cfp consistency errorClosedActions
Related to Ruby master - Bug #9454: The define_method(:class) segfaultClosed01/26/2014Actions
Actions

Also available in: Atom PDF