Project

General

Profile

Bug #3258

Segmentation fault in Bigdecimal.new

Added by tarui (Masaya Tarui) about 10 years ago. Updated about 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
ruby -v:
ruby 1.9.2dev (2010-05-07 trunk 27658) [i386-mswin32_90]
Backport:
[ruby-dev:41213]

Description

=begin
GC.stress = true
require 'bigdecimal'
1000.times{|i| puts BigDecimal.new("1" + "0"*i) }
を実行すると、

ruby 1.9.2dev (2010-05-07 trunk 27658) [i386-mswin32_90]
0.1E1
0.1E2
0.1E3
0.1E4
0.1E5
0.1E6
0.1E7
0.1E8
0.1E9
0.1E10
0.46454294919296E12
0.4294892378E12
0.42949672324294858116E16
/soft/ruby/build/t2.rb:3: [BUG] Segmentation fault
ruby 1.9.2dev (2010-05-07 trunk 27658) [i386-mswin32_90]

-- control frame ----------
c:0009 p:---- s:0022 b:0022 l:000021 d:000021 CFUNC :to_s
c:0008 p:---- s:0020 b:0020 l:000019 d:000019 CFUNC :puts
c:0007 p:---- s:0018 b:0018 l:000017 d:000017 CFUNC :puts
c:0006 p:0033 s:0014 b:0014 l:00220c d:000013 BLOCK /soft/ruby/build/t2.rb:3
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 FINISH
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :times
c:0003 p:0040 s:0006 b:0006 l:00220c d:00134c EVAL /soft/ruby/build/t2.rb:3
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:00220c d:00220c TOP


-- Ruby level backtrace information ----------------------------------------
/soft/ruby/build/t2.rb:3:in <main>'
/soft/ruby/build/t2.rb:3:in
times'
/soft/ruby/build/t2.rb:3:in block in <main>'
/soft/ruby/build/t2.rb:3:in
puts'
/soft/ruby/build/t2.rb:3:in puts'
/soft/ruby/build/t2.rb:3:in
to_s'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

のように落ちます。(それ以前に値がおかしくなっていますが)
bigdecimal.cのVpAllocにおいて、bufがvolatile宣言されていますが、対応する領域が最適化によって最後に使用された後に違う用途で再利用されているためGC対策として意味を成していません。
#私の環境ではif(szVal[i]=='-')のあたりで上書きされていました。
正しく対策するには内部値を使用し終わった後にRB_GC_GUARDを置く必要があると思います。

以下で直ることを確認しました。

Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c (リビジョン 27662)
+++ ext/bigdecimal/bigdecimal.c (作業コピー)
@@ -2593,7 +2593,7 @@
int sign=1;
Real *vp = NULL;
U_LONG mf = VpGetPrecLimit();

  • volatile VALUE buf;
  • VALUE buf;

    mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. /
    if(szVal) {
    @@ -2720,6 +2720,7 @@
    vp->MaxPrec = mx; /
    set max precision */
    VpSetZero(vp,sign);
    VpCtoV(vp, &(szVal[ipn]), ni, &(szVal[ipf]), nf, &(szVal[ipe]), ne);

  • RB_GC_GUARD(buf);
    return vp;
    }
    =end

#1

Updated by nobu (Nobuyoshi Nakada) about 10 years ago

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

=begin
This issue was solved with changeset r27665.
masaya, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

Also available in: Atom PDF