Bug #1330

BigDecimal オブジェクトを何度も使い回すと Bus Error が発生することがある

Added by Kenta Murata almost 3 years ago. Updated 10 months ago.

Status:Closed Start date:03/30/2009
Priority:Normal Due date:
Assignee:Tadashi Saito % Done:

0%

Category:ext
Target version:Ruby 1.8.8
ruby -v:ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]

Description

以下のように BigDecimal オブジェクトを何度も再利用すると BusError が起こります。

  $ ~/ruby-1.8.8-r23088/bin/ruby -rbigdecimal -ve '
    a = BigDecimal("10000000000000000000000000000000000000000")
    b = BigDecimal("0.0000000000000000000000000000001")
    1000000.times{ a + b }'
  ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]
  -e:4: [BUG] Bus Error
  ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]

  Abort trap

次のように、times のブロック内で何かを puts することで、これを回避できることが分かりました。

  $ ~/ruby-1.8.8-r23088/bin/ruby -rbigdecimal -ve '
    a = BigDecimal("10000000000000000000000000000000000000000")
    b = BigDecimal("0.0000000000000000000000000000001")
    1000000.times{ $stderr.puts ""; a + b }' 2>/dev/null
  ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]

ところが、puts の引数を省略すると Bus Error が復活します。

  $ ~/ruby-1.8.8-r23088/bin/ruby -rbigdecimal -ve '
    a = BigDecimal("10000000000000000000000000000000000000000")
    b = BigDecimal("0.0000000000000000000000000000001")
    1000000.times{ $stderr.puts; a + b }'
  ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]
  (非常に大量の改行文字は省略)
  -e:4: [BUG] Bus Error
  ruby 1.8.8dev (2009-03-28) [i386-darwin9.6.0]

  Abort trap

History

Updated by Shyouhei Urabe about 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Tadashi Saito

Updated by Tadashi Saito about 2 years ago

どうも、忘年会に行ったら突然「Assignしといたから」と言われた斎藤です。

最新のruby_1_8を手元の環境で試したところ、N.timesのNを増やしても、あるいは
GC.stress = trueを手前に入れても再現しませんでした。r23613でalloca()を
使わないようになったのが影響する気がしないでもないので、再度テストを
お願いできないでしょうか? >むらけんさん

Updated by Kenta Murata about 2 years ago

以下のように、再現されないことを確認しました。

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>     a = BigDecimal("10000000000000000000000000000000000000000")
>     b = BigDecimal("0.0000000000000000000000000000001")
>     1000000.times{ a + b }'
ruby 1.8.8dev (2009-12-21) [x86_64-darwin]

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>     a = BigDecimal("10000000000000000000000000000000000000000")
>     b = BigDecimal("0.0000000000000000000000000000001")
>     1000000.times{ $stderr.puts ""; a + b }' 2>/dev/null
ruby 1.8.8dev (2009-12-21) [x86_64-darwin]

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>     a = BigDecimal("10000000000000000000000000000000000000000")
>     b = BigDecimal("0.0000000000000000000000000000001")
>     1000000.times{ $stderr.puts; a + b }'
ruby 1.8.8dev (2009-12-21) [x86_64-darwin]

Updated by Yui NARUSE about 2 years ago

  • Status changed from Assigned to Closed

Updated by Kenta Murata about 2 years ago

アーキテクチャが違ってました。
i386 でもう一度試しましたが、再現しなかったので閉じて良いと思います。

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>    a = BigDecimal("10000000000000000000000000000000000000000")
>    b = BigDecimal("0.0000000000000000000000000000001")
>    1000000.times{ a + b }'
ruby 1.8.8dev (2009-12-21) [i386-darwin10.2.0]

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>    a = BigDecimal("10000000000000000000000000000000000000000")
>    b = BigDecimal("0.0000000000000000000000000000001")
>    1000000.times{ $stderr.puts ""; a + b }' 2>/dev/null
ruby 1.8.8dev (2009-12-21) [i386-darwin10.2.0]

$ /opt/ruby/ruby_1_8/bin/ruby -rbigdecimal -ve '
>    a = BigDecimal("10000000000000000000000000000000000000000")
>    b = BigDecimal("0.0000000000000000000000000000001")
>    1000000.times{ $stderr.puts; a + b }' 2>/dev/null
ruby 1.8.8dev (2009-12-21) [i386-darwin10.2.0]

Also available in: Atom PDF