Bug #4223

GC.stress = true で謎の ArgumentError

Added by Makoto Kishimoto over 3 years ago. Updated almost 3 years ago.

[ruby-dev:42907]
Status:Closed
Priority:Normal
Assignee:Kenta Murata
Category:-
Target version:1.9.3
ruby -v:- Backport:

Description

=begin
手元の環境で、trunk の r29690 以降で、次のようなスクリプトが、

# foo.rb
GC.stress = true
t = Time.local(2000)
File.utime(t + 1, t + 2, "foo.rb")

こんな感じに謎の ArgumentError になります

$ ruby19 -v foo.rb
ruby 1.9.3dev (2010-12-29 trunk 30417) [x86_64-freebsd8.2]
foo.rb:4:in utime': time out of system range (ArgumentError)
from foo.rb:4:in
'
=end

patch-bug4223.txt Magnifier (253 Bytes) Makoto Kishimoto, 07/07/2011 09:39 PM

patch-bug4223.txt Magnifier (611 Bytes) Makoto Kishimoto, 07/13/2011 09:48 AM

Associated revisions

Revision 32551
Added by Kenta Murata almost 3 years ago

  • bignum.c (bigsubint): add RBGC_GUARD. This patch is made by Makoto Kishimoto. fixes #4223
  • bignum.c (bigadd_int): ditto.

History

#1 Updated by Yui NARUSE almost 3 years ago

  • Status changed from Open to Feedback
  • Assignee set to Makoto Kishimoto

現在のtrunkで再現しませんがどうでしょう

#2 Updated by Makoto Kishimoto almost 3 years ago

私の手元の環境では変わってません。

$ cat foo.rb

foo.rb

GC.stress = true
t = Time.local(2000)
File.utime(t + 1, t + 2, "foo.rb")

$ ruby19 -v foo.rb
ruby 1.9.3dev (2011-06-26 trunk 32231) [x86_64-freebsd8.2]
foo.rb:4:in utime': time out of system range (ArgumentError)
from foo.rb:4:in
'

#3 Updated by Hiroshi Nakamura almost 3 years ago

  • Status changed from Feedback to Assigned
  • Assignee changed from Makoto Kishimoto to Yui NARUSE
  • Target version set to 1.9.3

#4 Updated by Yui NARUSE almost 3 years ago

  • Assignee changed from Yui NARUSE to Makoto Kishimoto

うーん、UFSでもZFSでも再現しなくて謎なので、再現できる岸本さんが頑張ってください

#5 Updated by Makoto Kishimoto almost 3 years ago

直りました。パッチ添付します

#6 Updated by Motohiro KOSAKI almost 3 years ago

直感的には、関数の最後でRBGCGUARD()しないといけない気がしますがどう思います? > むらけんさん

#7 Updated by Kenta Murata almost 3 years ago

  • ruby -v changed from ruby 1.9.3dev (2010-12-29 trunk 30417) [x86_64-freebsd8.2] to -

むらたです。

On Thursday, July 7, 2011 at 9:49 PM, Motohiro KOSAKI wrote:

直感的には、関数の最後でRBGCGUARD()しないといけない気がしますがどう思います? > むらけんさん

z = bignew(zn, RBIGNUM_SIGN(x));

ここで GC が走る可能性があって、そういう場合に x をガードする事が目的なんだと思います。
ですから、bigaddint の最初に RBGC_GUARD して良いです。

--
Kenta Murata
Sent with Sparrow (http://www.sparrowmailapp.com)

#8 Updated by Kenta Murata almost 3 years ago

むらたです。

On Thursday, July 7, 2011 at 9:49 PM, Motohiro KOSAKI wrote:

直感的には、関数の最後でRBGCGUARD()しないといけない気がしますがどう思います? > むらけんさん

z = bignew(zn, RBIGNUM_SIGN(x));

ここで GC が走る可能性があって、そういう場合に x をガードする事が目的なんだと思います。
ですから、bigaddint の最初に RBGC_GUARD して良いです。

--
Kenta Murata
Sent with Sparrow (http://www.sparrowmailapp.com)

#9 Updated by Motohiro KOSAKI almost 3 years ago

2011年7月8日19:34 Kenta Murata muraken@gmail.com:

むらたです。

On Thursday, July 7, 2011 at 9:49 PM, Motohiro KOSAKI wrote:

直感的には、関数の最後でRBGCGUARD()しないといけない気がしますがどう思います? > むらけんさん

z = bignew(zn, RBIGNUM_SIGN(x));

ここで GC が走る可能性があって、そういう場合に x をガードする事が目的なんだと思います。
ですから、bigaddint の最初に RBGC_GUARD して良いです。

あ、すいません。昨日僕のいない間に #ruby-jaで議論して後ろに移動させるという
結論になったみたいです。

22:49:17 途中に付けても無駄になることがある
22:50:09 最後じゃなくてもいいけど、ガードが必要な部分のあとにないとダメ
22:50:41 結局そういう事になったのか
22:51:41 では、私のパッチよりもっとあとでないとまずいですね
22:51:47 経験則的に
22:52:25 前に置いてるの沢山ありますよ たしか。
22:52:41 xdsを参照してる最後の場所より後だから、同じ関数のwhileの後
22:53:15 RBGCGUARDをもうちょい工夫すればいいのかなぁ
22:53:27 全く同じ構造のコードだから bigsubint にも要るかな
22:53:27 matzにこういわれたので、
22:53:28 {unak
away} http://mla.n-z.jp/?ruby-dev=40942
22:53:48 VC向けのRBGCGUARDは試行錯誤した
22:54:16 フロー解析して最適化されちゃうなら、工夫じゃどうにもならなさそうな
22:54:35 経験的にOKとしかいいようがない。

#10 Updated by Motohiro KOSAKI almost 3 years ago

2011年7月8日19:34 Kenta Murata muraken@gmail.com:

むらたです。

On Thursday, July 7, 2011 at 9:49 PM, Motohiro KOSAKI wrote:

直感的には、関数の最後でRBGCGUARD()しないといけない気がしますがどう思います? > むらけんさん

z = bignew(zn, RBIGNUM_SIGN(x));

ここで GC が走る可能性があって、そういう場合に x をガードする事が目的なんだと思います。
ですから、bigaddint の最初に RBGC_GUARD して良いです。

あ、すいません。昨日僕のいない間に #ruby-jaで議論して後ろに移動させるという
結論になったみたいです。

22:49:17 途中に付けても無駄になることがある
22:50:09 最後じゃなくてもいいけど、ガードが必要な部分のあとにないとダメ
22:50:41 結局そういう事になったのか
22:51:41 では、私のパッチよりもっとあとでないとまずいですね
22:51:47 経験則的に
22:52:25 前に置いてるの沢山ありますよ たしか。
22:52:41 xdsを参照してる最後の場所より後だから、同じ関数のwhileの後
22:53:15 RBGCGUARDをもうちょい工夫すればいいのかなぁ
22:53:27 全く同じ構造のコードだから bigsubint にも要るかな
22:53:27 matzにこういわれたので、
22:53:28 {unak
away} http://mla.n-z.jp/?ruby-dev=40942
22:53:48 VC向けのRBGCGUARDは試行錯誤した
22:54:16 フロー解析して最適化されちゃうなら、工夫じゃどうにもならなさそうな
22:54:35 経験的にOKとしかいいようがない。

#11 Updated by Motohiro KOSAKI almost 3 years ago

  • Priority changed from Low to Normal

#12 Updated by Kenta Murata almost 3 years ago

むらたです。

On Friday, July 8, 2011 at 7:55 PM, KOSAKI Motohiro wrote:

あ、すいません。昨日僕のいない間に #ruby-jaで議論して後ろに移動させるという
結論になったみたいです。

22:49:17 途中に付けても無駄になることがある
22:50:09 最後じゃなくてもいいけど、ガードが必要な部分のあとにないとダメ
22:50:41 結局そういう事になったのか
22:51:41 では、私のパッチよりもっとあとでないとまずいですね
22:51:47 経験則的に
22:52:25 前に置いてるの沢山ありますよ たしか。
22:52:41 xdsを参照してる最後の場所より後だから、同じ関数のwhileの後
22:53:15 RBGCGUARDをもうちょい工夫すればいいのかなぁ
22:53:27 全く同じ構造のコードだから bigsubint にも要るかな
22:53:27 matzにこういわれたので、
22:53:28 {unak
away} http://mla.n-z.jp/?ruby-dev=40942
22:53:48 VC向けのRBGCGUARDは試行錯誤した
22:54:16 フロー解析して最適化されちゃうなら、工夫じゃどうにもならなさそうな
22:54:35 経験的にOKとしかいいようがない。

なんと、RBGCGUARD の意味がコンパイラの進化に伴なって変わってる事を知りませんでした。

おとなしく bigdecimal.c を見なおして来ます orz
--
Kenta Murata
Sent with Sparrow (http://www.sparrowmailapp.com)

#13 Updated by Kenta Murata almost 3 years ago

むらたです。

On Friday, July 8, 2011 at 7:55 PM, KOSAKI Motohiro wrote:

あ、すいません。昨日僕のいない間に #ruby-jaで議論して後ろに移動させるという
結論になったみたいです。

22:49:17 途中に付けても無駄になることがある
22:50:09 最後じゃなくてもいいけど、ガードが必要な部分のあとにないとダメ
22:50:41 結局そういう事になったのか
22:51:41 では、私のパッチよりもっとあとでないとまずいですね
22:51:47 経験則的に
22:52:25 前に置いてるの沢山ありますよ たしか。
22:52:41 xdsを参照してる最後の場所より後だから、同じ関数のwhileの後
22:53:15 RBGCGUARDをもうちょい工夫すればいいのかなぁ
22:53:27 全く同じ構造のコードだから bigsubint にも要るかな
22:53:27 matzにこういわれたので、
22:53:28 {unak
away} http://mla.n-z.jp/?ruby-dev=40942
22:53:48 VC向けのRBGCGUARDは試行錯誤した
22:54:16 フロー解析して最適化されちゃうなら、工夫じゃどうにもならなさそうな
22:54:35 経験的にOKとしかいいようがない。

なんと、RBGCGUARD の意味がコンパイラの進化に伴なって変わってる事を知りませんでした。

おとなしく bigdecimal.c を見なおして来ます orz
--
Kenta Murata
Sent with Sparrow (http://www.sparrowmailapp.com)

#14 Updated by Makoto Kishimoto almost 3 years ago

新しいパッチです。
更新点は、
* bigsubint() も対策した
* RB
GC_GUARD をコントロールフロー的に十分に後ろの場所に移動した
の 2 点です。
コミット(とバックポート)とクローズ(でいいですよね)お願いします。

#15 Updated by Motohiro KOSAKI almost 3 years ago

  • Assignee changed from Makoto Kishimoto to Kenta Murata

これは1.9.3 ターゲットのままでいいですよね? > むらけんさん

#16 Updated by Kenta Murata almost 3 years ago

はい。やっておきます。

#17 Updated by Kenta Murata almost 3 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r32551.
Makoto, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • bignum.c (bigsubint): add RBGC_GUARD. This patch is made by Makoto Kishimoto. fixes #4223
  • bignum.c (bigadd_int): ditto.

#18 Updated by Makoto Kishimoto almost 3 years ago

RBGCGUARD マクロについて簡単にまとめておきます
* オブジェクトの中身を指してるポインタがCコード中にあって参照中なのに、オブジェクトを指すポインタ(VALUE)がどこにもなくなっちゃってGCに回収されるのを防ぐ
* 関数の最初のほうにあるコードがけっこうある。展開内容を工夫して、それでも困らないようにがんばってはいるけど、コンパイラによる高度な最適化で、結構わからない
* ソースコードのコントロールフロー中、オブジェクトの中身にアクセスしていて、かつGCが起きうる場所(rubyコードが動く、オブジェクトを作る)よりも後ろに置くことが、安全のためには必要。将来コードを追加することを考えると、より(コントロールフロー的に)後ろのほうに

Also available in: Atom PDF