[#12763] NameError (Re: [ruby-list:29101] Re: nil.to_f) — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

24 messages 2001/04/04
[#12765] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — "K.Kosako" <kosako@...> 2001/04/04

Yukihiro Matsumotoさんの

[#12767] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — matz@... (Yukihiro Matsumoto) 2001/04/04

まつもと ゆきひろです

[#12787] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — "K.Kosako" <kosako@...> 2001/04/06

Yukihiro Matsumotoさんの

[#12789] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — matz@... (Yukihiro Matsumoto) 2001/04/06

まつもと ゆきひろです

[#12790] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — "K.Kosako" <kosako@...> 2001/04/06

Yukihiro Matsumotoさんの

[#12792] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — matz@... (Yukihiro Matsumoto) 2001/04/06

まつもと ゆきひろです

[#12838] Re: NameError (Re: [ruby-list:29101] Re: nil.to_f) — "K.Kosako" <kosako@...> 2001/04/10

Yukihiro Matsumotoさんの

[#12795] recursive malloc / fork deadlock / thread deadlock — "Akinori MUSHA" <knu@...>

 添付のスクリプトで、いくつかのプラットフォームで問題が発生する

43 messages 2001/04/07
[#12799] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/07

まつもと ゆきひろです

[#12801] Re: recursive malloc / fork deadlock / thread deadlock — nobu.nakada@... 2001/04/08

なかだです。

[#12802] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/09

まつもと ゆきひろです

[#12822] Re: recursive malloc / fork deadlock / thread deadlock — nobu.nakada@... 2001/04/09

なかだです。

[#12827] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/09

まつもと ゆきひろです

[#12836] Re: recursive malloc / fork deadlock / thread deadlock — nobu.nakada@... 2001/04/10

なかだです。

[#12840] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/10

まつもと ゆきひろです

[#12852] Re: recursive malloc / fork deadlock / thread deadlock — nobu.nakada@... 2001/04/10

なかだです。

[#12854] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/10

まつもと ゆきひろです

[#12857] Re: recursive malloc / fork deadlock / thread deadlock — nobu.nakada@... 2001/04/10

なかだです。

[#12859] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/10

まつもと ゆきひろです

[#12862] Re: recursive malloc / fork deadlock / thread deadlock — GOTOU Yuuzou <gotoyuzo@...> 2001/04/10

ごとうゆうぞうです。

[#12866] Re: recursive malloc / fork deadlock / thread deadlock — matz@... (Yukihiro Matsumoto) 2001/04/10

まつもと ゆきひろです

[#12878] Re: recursive malloc / fork deadlock / thread deadlock — GOTOU Yuuzou <gotoyuzo@...> 2001/04/11

ごとうゆうぞうです。

[#12888] Re: recursive malloc / fork deadlock / thread deadlock — GOTOU Yuuzou <gotoyuzo@...> 2001/04/11

ごとうゆうぞうです。

[#12892] Re: recursive malloc / fork deadlock / thread deadlock — Takahiro Kambe <taca@...> 2001/04/12

完全に理解せずに書いています。

[#12895] Re: recursive malloc / fork deadlock / thread deadlock — Jun Adachi <adachi@...> 2001/04/12

安達@沖データと申します。

[#12898] Re: recursive malloc / fork deadlock / thread deadlock — GOTOU Yuuzou <gotoyuzo@...> 2001/04/12

ごとうゆうぞうです。

[#12830] 1.6.4 preview — "Akinori MUSHA" <knu@...>

 そろそろ FreeBSD 4.3-RELEASE 前の ports のフリーズが迫っている

23 messages 2001/04/09
[#12844] Re: 1.6.4 preview — matz@... (Yukihiro Matsumoto) 2001/04/10

まつもと ゆきひろです

[#12921] ObjectSpace.each_object(Symbol) — keiju@... (Keiju ISHITSUKA)

けいじゅ@日本ラショナルソフトウェアです.

23 messages 2001/04/13
[#12923] Re: ObjectSpace.each_object(Symbol) — matz@... (Yukihiro Matsumoto) 2001/04/13

まつもと ゆきひろです

[#12928] Re: ObjectSpace.each_object(Symbol) — Hisayasu Nakao <h-nakao@...> 2001/04/13

中尾@富士通です。

[#12929] Re: ObjectSpace.each_object(Symbol) — matz@... (Yukihiro Matsumoto) 2001/04/13

まつもと ゆきひろです

[#12934] Re: ObjectSpace.each_object(Symbol) — keiju@... (石塚圭樹) 2001/04/13

けいじゅ@日本ラショナルソフトウェアです.

[#12941] Re: ObjectSpace.each_object(Symbol) — matz@... (Yukihiro Matsumoto) 2001/04/13

まつもと ゆきひろです

[ruby-dev:12795] recursive malloc / fork deadlock / thread deadlock

From: "Akinori MUSHA" <knu@...>
Date: 2001-04-07 12:10:04 UTC
List: ruby-dev #12795
 添付のスクリプトで、いくつかのプラットフォームで問題が発生する
ことが分かりました。

 見られる現象は、さまざまで、次の三つが確認されています。

A. recursive malloc:
	malloc/realloc/free が処理中に再入されてエラー。

    ruby in realloc(): error: recursive call.

	コアを吐く場所は毎回違うが、一例を挙げると

    (gdb) where
    #0  0x2817acc0 in kill () from /usr/lib/libc.so.5
    #1  0x281cbe65 in abort () from /usr/lib/libc.so.5
    #2  0x281ca9aa in isatty () from /usr/lib/libc.so.5
    #3  0x281ca9d8 in isatty () from /usr/lib/libc.so.5
    #4  0x281cbbae in realloc () from /usr/lib/libc.so.5
    #5  0x8068cfd in ruby_xrealloc (ptr=0x819e000, size=12896) at gc.c:137
    #6  0x806143d in rb_thread_save_context (th=0x816fc00) at eval.c:7075
    #7  0x806227f in rb_thread_schedule () at eval.c:7510
    #8  0x806321e in catch_timer (sig=26) at eval.c:8032
    #9  0x280f961e in _thread_sig_wrapper () from /usr/lib/libc_r.so.5
    #10 0x0 in ?? ()
    (gdb) f 5
    #5  0x8068cfd in ruby_xrealloc (ptr=0x819e000, size=12896) at gc.c:137
    137	    RUBY_CRITICAL(mem = realloc(ptr, size));
    (gdb) list
    132		rb_raise(rb_eArgError, "negative re-allocation size");
    133	    }
    134	    if (!ptr) return xmalloc(size);
    135	    if (size == 0) size = 1;
    136	    malloc_memories += size;
    137	    RUBY_CRITICAL(mem = realloc(ptr, size));
    138	    if (!mem) {
    139		rb_gc();
    140		RUBY_CRITICAL(mem = realloc(ptr, size));
    141		if (!mem)
    (gdb) f 6
    #6  0x806143d in rb_thread_save_context (th=0x816fc00) at eval.c:7075
    7075		REALLOC_N(th->stk_ptr, VALUE, len);
    (gdb) list
    7070	    len = stack_length(&pos);
    7071	    th->stk_len = 0;
    7072	    th->stk_pos = (rb_gc_stack_start<pos)?rb_gc_stack_start
    7073					         :rb_gc_stack_start - len;
    7074	    if (len > th->stk_max) {
    7075		REALLOC_N(th->stk_ptr, VALUE, len);
    7076		th->stk_max = len;
    7077	    }
    7078	    th->stk_len = len;
    7079	    FLUSH_REGISTER_WINDOWS; 
    
B. fork deadlock:
	thread の中で fork したところでそのスレッドが固まる
	(Ruby側からは検知できないアイドリング状態)

	^Cを押すと

    /usr/local/lib/ruby/1.6/thread.rb:178:in `stop': Interrupt
    	from /usr/local/lib/ruby/1.6/thread.rb:178:in `pop'
    	from /usr/local/lib/ruby/1.6/thread.rb:173:in `loop'
    	from /usr/local/lib/ruby/1.6/thread.rb:173:in `pop'
    	from /home/knu/www/thread_test.rb:60
    	from /home/knu/www/thread_test.rb:59:in `times'
    	from /home/knu/www/thread_test.rb:59

	となる。

C. thread deadlock:
	意図した処理は終わっていないのに、すべてのスレッドが
	止まってしまい、Rubyがそれを検知して終了

    deadlock 0x20000398008: 2:0  - /usr/lib/ruby/1.6/thread.rb:51
    deadlock 0x200003bea50: 2:0 (main) - /usr/lib/ruby/1.6/thread.rb:163
    deadlock 0x20000397b80: 2:0  - /usr/lib/ruby/1.6/thread.rb:51
    /usr/lib/ruby/1.6/thread.rb:51:in `pop': Thread: deadlock (fatal)
    	from /usr/lib/ruby/1.6/thread.rb:170:in `loop'
    	from /usr/lib/ruby/1.6/thread.rb:170:in `pop'
    	from thread_test.rb:60
    	from thread_test.rb:59:in `times'
    	from thread_test.rb:59


 各プラットフォームにて確認されている現象は、次の通りです。

FreeBSD/i386: (私)
	A, B, C

Cygwin: (znz さんより)
	B

Linux/alpha: (やまださんより)
	C

Linux/i386, NetBSD/i386: (私)
	正常終了

なお、 FreeBSD/i386 での A は、標準の malloc ライブラリでも、
dmalloc (http://dmalloc.com/) を使っても再入エラーが出るのは
同様でした。また、コンパイルおよびリンク時の pthread サポートの
有無にも関わりなく発生しています。

 Ruby 自体は最新の 1.6 と最新の 1.7 で確認しています。

 明らかに race condition によって起きているので、一発では再現
しないかもしれませんが、何度かやったり -j と -t のパラメータを
適当に調節することで(起こる環境では)再現できるはずです。


 どうも、この問題は Thread と popen (pipe_open) の組み合わせで
起こっているようです。(*) の部分を IO::popen() にしても結果は
まったく同じですが、単に system() を呼び出すだけならば問題ない
みたいです。


 というわけで、よろしくお願いします。

-- 
                     /
                    /__  __            Akinori.org / MUSHA.org
                   / )  )  ) )  /     FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ /  ( (__(  @ iDaemons.org / and.or.jp

"We're only at home when we're on the run, on the wing, on the fly"

#!/usr/bin/env ruby

require 'thread'
require 'getopts'

getopts('g', 'j:4', 't:50')

if $OPT_g
  GC.disable
end

# ntasks 個のデータを nhands 人で協力して処理する
nhands = $OPT_j.to_i
ntasks = $OPT_t.to_i

# 排他用
mutex = Mutex.new

# 完了した人は合図として queue に自分の番号を push するものとする
done = Queue.new

# データを生成
tasks = Array.new(ntasks)
s = 'aaaa'
for i in 0...ntasks
  tasks[i] = s.dup
  s.succ!
end

# 人を稼働
nhands.times { |handno|
  Thread.start {
    str = nil

    # データが残っているうちは取り出して処理
    loop {
      # 有無のチェックから取り出しまではアトミック
      mutex.synchronize {
        if tasks.empty?
          done.push handno
          Thread.exit
        end

        str = tasks.shift
      }

      printf "%d: %3d:%3d: <== %s\n", handno, tasks.size, ntasks, str

      # 大文字化 (*)
      result = `echo #{str} | tr a-z A-Z`.chomp
#     result = IO::popen("echo #{str} | tr a-z A-Z").read.chomp
#     system("echo #{str} | tr a-z A-Z > /dev/null"); result = str.upcase

      printf "%d: %3d:%3d: ==> %s\n", handno, tasks.size, ntasks, result
    }
  }
}

# 全員が終わるまで待つ
nhands.times { |i|
  handno = done.pop
  puts "#{handno}: done!"
}

In This Thread

Prev Next