Project

General

Profile

Actions

Bug #4238

closed

GC.stress 下で OptionParser で設定のない引数をパースさせると core

Added by metanest (Makoto Kishimoto) over 13 years ago. Updated almost 13 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.3dev (2011-01-06 trunk 30471) [x86_64-freebsd8.2]
Backport:
[ruby-dev:42963]

Description

=begin
r29832 以降で起きます

以下のようなスクリプトを実行すると、

$ cat optparse-core.rb
require "optparse"

parser = OptionParser.new
GC.stress
parser.parse! ['-a']

以下のように core を吐きます。

$ ruby19 optparse-core.rb
/usr/local/lib/ruby/1.9.1/optparse.rb:233: [BUG] Segmentation fault
ruby 1.9.3dev (2011-01-06 trunk 30471) [x86_64-freebsd8.2]

-- Control frame information -----------------------------------------------
c:0026 p:---- s:0116 b:0116 l:000115 d:000115 CFUNC :each
c:0025 p:---- s:0114 b:0114 l:0021f0 d:000113 IFUNC
c:0024 p:---- s:0112 b:0112 l:000111 d:000111 CFUNC :call
c:0023 p:0058 s:0109 b:0109 l:001ad0 d:001ad0 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:233
c:0022 p:0039 s:0101 b:0101 l:000100 d:000100 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:248
c:0021 p:0033 s:0095 b:0095 l:000094 d:000094 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:253
c:0020 p:0031 s:0085 b:0085 l:000084 d:000084 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:658
c:0019 p:0020 s:0077 b:0077 l:000068 d:000076 BLOCK /usr/local/lib/ruby/1.9.1/optparse.rb:1509
c:0018 p:---- s:0074 b:0074 l:000073 d:000073 FINISH
c:0017 p:---- s:0072 b:0072 l:000071 d:000071 CFUNC :reverse_each
c:0016 p:0013 s:0069 b:0069 l:000068 d:000068 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1508
c:0015 p:0023 s:0063 b:0063 l:001bd8 d:000e38 BLOCK /usr/local/lib/ruby/1.9.1/optparse.rb:1540
c:0014 p:---- s:0061 b:0061 l:000060 d:000060 FINISH
c:0013 p:---- s:0059 b:0059 l:000058 d:000058 CFUNC :catch
c:0012 p:0051 s:0055 b:0053 l:001bd8 d:001bd8 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1539
c:0011 p:0032 s:0046 b:0046 l:000030 d:000045 BLOCK /usr/local/lib/ruby/1.9.1/optparse.rb:1379
c:0010 p:0296 s:0043 b:0043 l:000030 d:000042 BLOCK /usr/local/lib/ruby/1.9.1/optparse.rb:1371
c:0009 p:---- s:0037 b:0037 l:000036 d:000036 FINISH
c:0008 p:---- s:0035 b:0035 l:000034 d:000034 CFUNC :catch
c:0007 p:0062 s:0031 b:0031 l:000030 d:000030 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1346
c:0006 p:0024 s:0021 b:0021 l:000020 d:000020 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1340
c:0005 p:0038 s:0016 b:0016 l:000015 d:000015 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1431
c:0004 p:0054 s:0011 b:0011 l:000010 d:000010 METHOD /usr/local/lib/ruby/1.9.1/optparse.rb:1452
c:0003 p:0063 s:0007 b:0007 l:0016b8 d:000ec0 EVAL optparse-core.rb:5
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0016b8 d:0016b8 TOP

-- Ruby level backtrace information ----------------------------------------
optparse-core.rb:5:in <main>' /usr/local/lib/ruby/1.9.1/optparse.rb:1452:in parse!'
/usr/local/lib/ruby/1.9.1/optparse.rb:1431:in permute!' /usr/local/lib/ruby/1.9.1/optparse.rb:1340:in order!'
/usr/local/lib/ruby/1.9.1/optparse.rb:1346:in parse_in_order' /usr/local/lib/ruby/1.9.1/optparse.rb:1346:in catch'
/usr/local/lib/ruby/1.9.1/optparse.rb:1371:in block in parse_in_order' /usr/local/lib/ruby/1.9.1/optparse.rb:1379:in rescue in block in parse_in_order'
/usr/local/lib/ruby/1.9.1/optparse.rb:1539:in complete' /usr/local/lib/ruby/1.9.1/optparse.rb:1539:in catch'
/usr/local/lib/ruby/1.9.1/optparse.rb:1540:in block in complete' /usr/local/lib/ruby/1.9.1/optparse.rb:1508:in visit'
/usr/local/lib/ruby/1.9.1/optparse.rb:1508:in reverse_each' /usr/local/lib/ruby/1.9.1/optparse.rb:1509:in block in visit'
/usr/local/lib/ruby/1.9.1/optparse.rb:658:in complete' /usr/local/lib/ruby/1.9.1/optparse.rb:253:in complete'
/usr/local/lib/ruby/1.9.1/optparse.rb:248:in candidate' /usr/local/lib/ruby/1.9.1/optparse.rb:233:in candidate'
/usr/local/lib/ruby/1.9.1/optparse.rb:233:in call' /usr/local/lib/ruby/1.9.1/optparse.rb:233:in each'

-- Other runtime information -----------------------------------------------

  • Loaded script: optparse-core.rb

  • Loaded features:

    0 enumerator.so
    1 /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.2/enc/encdb.so
    2 /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.2/enc/trans/transdb.so
    3 /usr/local/lib/ruby/1.9.1/optparse.rb

[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

Abort trap: 6 (core dumped)
=end

Actions #1

Updated by nagachika (Tomoyuki Chikanaga) over 13 years ago

=begin
Ubuntu 上で gcc-4.3.3, -O3 つきでビルドした ruby で再現しました。
再現コードを削ってみたところ以下でも起きました。

% cat bug4238.rb
def a(&blk)
blk.call do |i| p i end
end

GC.stress = true
a(&([0,1].method(:each)))

% ./ruby-trunk -v bug4238.rb
ruby 1.9.3dev (2011-01-06 trunk 30474) [i686-linux]
0
bug4238.rb:2: [BUG] Segmentation fault
ruby 1.9.3dev (2011-01-06 trunk 30474) [i686-linux]

-- Control frame information -----------------------------------------------
c:0009 p:0012 s:0024 b:0022 l:000658 d:000021 BLOCK bug4238.rb:2
c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISH
c:0007 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC :each
c:0006 p:---- s:0015 b:0015 l:000408 d:000014 IFUNC
c:0005 p:---- s:0013 b:0013 l:000012 d:000012 CFUNC :call
c:0004 p:0012 s:0010 b:0010 l:001e10 d:001e10 METHOD bug4238.rb:2
c:0003 p:0056 s:0006 b:0006 l:000bdc d:000e34 EVAL bug4238.rb:6
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:000bdc d:000bdc TOP

-- Ruby level backtrace information ----------------------------------------
bug4238.rb:6:in <main>' bug4238.rb:2:in a'
bug4238.rb:2:in call' bug4238.rb:2:in each'
bug4238.rb:2:in `block in a'

-- C level backtrace information -------------------------------------------
Unexpected directory number 1 in ./ruby-trunk
Unexpected directory number 1 in ./ruby-trunk
Unexpected directory number 1 in ./ruby-trunk
Unexpected directory number 1 in ./ruby-trunk
Unexpected directory number 1 in ./ruby-trunk
./ruby-trunk [0x8172505] vm_dump.c:797
./ruby-trunk [0x81b4d71] error.c:249
./ruby-trunk(rb_bug+0x28) [0x81b4e08] error.c:266
./ruby-trunk [0x80feed5] signal.c:624
[0xb78d0410]
./ruby-trunk [0x8168524] vm_insnhelper.c:1344
./ruby-trunk [0x8168ecc] vm.c:1150
./ruby-trunk(rb_yield+0x4f) [0x817073f] vm.c:591
./ruby-trunk(rb_ary_each+0x41) [0x81838e1] array.c:1474
./ruby-trunk [0x816a271] vm_eval.c:79
./ruby-trunk(rb_method_call+0x151) [0x805f1f1] proc.c:1431
./ruby-trunk [0x805f4b1] proc.c:1816
./ruby-trunk [0x81610f1] vm_insnhelper.c:729
./ruby-trunk [0x816f1f6] vm.c:607
./ruby-trunk [0x8061e05] proc.c:559
./ruby-trunk [0x815cb3d] vm_insnhelper.c:316
./ruby-trunk [0x8161eb9] vm_insnhelper.c:403
./ruby-trunk [0x81636ac] insns.def:1010
./ruby-trunk [0x8168ecc] vm.c:1150
./ruby-trunk(rb_iseq_eval_main+0x1da) [0x816922a] vm.c:1391
./ruby-trunk [0x805b772] eval.c:225
./ruby-trunk(ruby_run_node+0x32) [0x805d242] eval.c:272
./ruby-trunk [0x805ab40] main.c:38
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb76f2775]
./ruby-trunk [0x805aa41] ../sysdeps/i386/elf/start.S:119

=end

Actions #2

Updated by nagachika (Tomoyuki Chikanaga) over 13 years ago

=begin
以下のように proc_call() に GC 除けを追加することで、わたしの環境では OptionParser を使った例も、
縮小版も SEGV が起きなくなりました(ruby 1.9.3dev (2011-01-18 trunk 30590) [i686-linux], gcc-4.3.3 optflags=-O3)。
いかがでしょうか。

diff --git a/proc.c b/proc.c
index 9ecf626..18c7393 100644
--- a/proc.c
+++ b/proc.c
@@ -543,16 +543,16 @@ proc_call(int argc, VALUE *argv, VALUE procval)
rb_proc_t *proc;
rb_block_t *blockptr = 0;
rb_iseq_t *iseq;

  • VALUE passed_procval;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
    if (rb_block_given_p()) {

  •  rb_proc_t *proc;
    
  •  VALUE procval;
    
  •  procval = rb_block_proc();
    
  •  GetProcPtr(procval, proc);
    
  •  blockptr = &proc->block;
    
  •  rb_proc_t *passed_proc;
    
  •  RB_GC_GUARD(passed_procval) = rb_block_proc();
    
  •  GetProcPtr(passed_procval, passed_proc);
    
  •  blockptr = &passed_proc->block;
    
    }
    }

=end

Actions #3

Updated by metanest (Makoto Kishimoto) over 13 years ago

=begin
note-2 のパッチで私のほうでも SEGV が起きなくなりました。
=end

Actions #4

Updated by kosaki (Motohiro KOSAKI) over 13 years ago

  • Status changed from Open to Closed

=begin
直ったとのことなので代理コミットしときました。Chikanagaさんは早くまつもとさんに言ってコミット権をもらうべきだと思います。

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0