ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
From: ncopa@alpinelinux•org
To: ruby-dev@ruby-lang.org
Subject: [ruby-dev:50567] [Ruby trunk Bug#14387] Ruby 2.5 を Alpine Linux で実行すると比較的浅めで SystemStackError 例外になる
Date: Mon, 11 Jun 2018 13:44:23 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-72467.20180611134422.65fbc3edc5811925@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-14387.20180124002916@ruby-lang.org

Issue #14387 has been updated by ncopa (Natanael Copa).


wanabe (_ wanabe) wrote:
> It seems to be reasonable not to rely `pthread_getattr_np()` on `defined(__linux__) && !defined(__GLIBC__)` environment because the function has suffix ["_np"](https://bugs.ruby-lang.org/issues/14387#note-12).
> I guess it would be ideal if ruby relies `pthread_getattr_np()` on only tested environments like as `defined(__linux__) && defined(__GLIBC__)`, but it is too much pain to follow / test other environments.

I agree that `defined(__linux__) && defined(__GLIBC__)` is better. Note that there are some non-linux glibc variants too but I would expect the `pthread_getattr_np()` call work as documented in the GNU libc manual, regarless if kernel is linux, hurd or anything else, so it should be enough with `defined(__GLIBC__)`.

> [ncopa's 2nd patch](https://bugs.ruby-lang.org/issues/14387#note-13) has a side effect as [commented](https://bugs.ruby-lang.org/issues/14387#note-16).
> So I think [1st patch](https://bugs.ruby-lang.org/issues/14387#note-10) is more pragmatic.
> 
> Naruse-san (or other?):
> How about https://bugs.ruby-lang.org/issues/14387#note-10 patch?

That patch is a workaround only and not a fix. It will cause the code to skip the `reserve_stack` call so behavior will differ from Linux systems with glibc. The second patch fixes the issue properly, even if it can be disputed if the `reserve_stack` is a good idea in the first place.

----------------------------------------
Bug #14387: Ruby 2.5 を Alpine Linux で実行すると比較的浅めで SystemStackError 例外になる
https://bugs.ruby-lang.org/issues/14387#change-72467

* Author: koshigoe (Masataka SUZUKI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux-musl]
* Backport: 2.3: DONTNEED, 2.4: DONTNEED, 2.5: REQUIRED
----------------------------------------
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

## 再現

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

~~~ ruby
# 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--------------------------------
0001-thread_pthread.c-make-get_main_stack-portable-on-lin.patch (2.61 KB)


-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2018-06-11 13:44 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-14387.20180124002916@ruby-lang.org>
2018-01-24  0:29 ` [ruby-dev:50421] [Ruby trunk Bug#14387] Ruby 2.5 を Alpine Linux で実行すると比較的浅めで SystemStackError 例外になる koshigoeb
2018-01-25 23:02 ` [ruby-dev:50433] " s.wanabe
2018-01-26  2:54 ` [ruby-dev:50435] " daniel.ltw
2018-01-26  3:38 ` [ruby-dev:50436] " mame
2018-01-29  9:28 ` [ruby-dev:50444] " craig
2018-01-29 19:31 ` [ruby-dev:50451] " daniel.ltw
2018-01-30  3:42 ` [ruby-dev:50452] " s.wanabe
2018-02-03 23:07 ` [ruby-dev:50463] " james
2018-03-08 13:32 ` [ruby-dev:50494] " ncopa
2018-03-13 17:41 ` [ruby-dev:50497] " ncopa
2018-03-16 12:57 ` [ruby-dev:50499] " ncopa
2018-04-05 17:16 ` [ruby-dev:50517] " j
2018-04-06  3:14 ` [ruby-dev:50519] " naruse
2018-05-20 16:17 ` [ruby-dev:50549] " jnardone
2018-05-23  0:32 ` [ruby-dev:50550] " s.wanabe
2018-06-02  1:23 ` [ruby-dev:50556] " naruse
2018-06-10 10:49 ` [ruby-dev:50564] " s.wanabe
2018-06-11 12:22 ` [ruby-dev:50565] " ncopa
2018-06-11 12:43 ` [ruby-dev:50566] " ncopa
2018-06-11 13:44 ` ncopa [this message]
2019-12-15  3:21 ` [ruby-dev:50886] [Ruby master " h.shimoyama

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-72467.20180611134422.65fbc3edc5811925@ruby-lang.org \
    --to=ruby-dev@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).