From: Koji Arai Date: 2002-09-21T15:26:50+09:00 Subject: [ruby-dev:18322] Re: rubicon on EWS4800 新井です。 In message "[ruby-dev:18285] rubicon on EWS4800" on 14 Sep 2002 02:48:59 +0900, Koji Arai wrote: > 新井です。 > > rubicon をEWS4800で試しました。 追試しました。 > @@ -298,6 +298,7 @@ > assert_equal("wombat\n", f.gets) > assert_nil(f.puts("koala")) > f.rewind > + assert_equal("wombat\n", f.gets) > assert_equal("wombat\n", f.gets) > assert_equal("koala\n", f.gets) > } > > ずテストを飛ばしてます。後者はこれまた謎なのですが、このよう > に修正しないとテストが通りません。(これも要調査・・・っと昔 > から思ってるんだけどなかなか手がつけられない) これは、EWS4800 でのstdioの挙動がそうなるようです。C で書い ても同様になりました。man には、 ファイルが更新モードでオープンされると、その stream 上では入 力 も 出 力 も 両 方 行 うことができます。ただし、入力の後に fflush(3S) や fseek(3S) あるいは fsetpos(3S) や rewind(3S) を 介 在 さ せ ず に 直接出力を続けたり、出力の後に fseek や fsetpos あるいは rewind を介在させずに直接入力を続けたり、あ るいはエンド・オブ・ファイルを検出する入力操作なしに出力の後 に直接入力を続けたりすることはできません。 っとあるので、このせいかも。仕方ないですね。 > TestThread は、途中 ^C を入れないとテストが継続しませんでし > た。 これは単に時間がかかってるだけだとわかりました。 | def test_s_critical= | | -略- | | 100000.times { |i| Math.sin(i) ** Math.tan(i/2) } | assert_equal(saved, count) | | Thread.critical = false | 100000.times { |i| Math.sin(i) ** Math.tan(i/2) } | assert(saved != count) | end の回数を一桁減らしてもらえるとうれしかったりします。EWS4800 はとっても遅いので(苦笑)。 > TestIO: > ------- > ./TestIO.rb:631:in `test_pid'(TestIO) > ....Expected: "<20773> " > ....But was: "<20772>" > ./TestIO.rb:208:in `test_s_popen_spawn'(TestIO) > ./TestIO.rb:198:in `dont' > ./TestIO.rb:198:in `test_s_popen_spawn' > ....Expected: "<12> " > ....But was: "<0>" これは、Solaris と同じ対処をすることで通りました。 | def test_pid | assert_nil($stdin.pid) | pipe = nil | Solaris.only do | pipe = IO.popen("exec #$interpreter -e 'p $$'", "r") | end | Solaris.dont do | pipe = IO.popen("#$interpreter -e 'p $$'", "r") | end の Solaris.only/dont のとこです。 あと、以下はこのメールの本題なのですが、2002-09-17 版で rubicon の TestThread で SEGV することがあります。落ちる箇所 周辺にデバッグ出力を埋め込んで実行したところ | th->stk_ptr = 6453a8, th->stk_len = 10247, th->stk_max = 10247 | o | th->stk_ptr = 0, th->stk_len = 10247, th->stk_max = 0 | realloc ptr = 65a590 | o | th->stk_ptr = 65a590, th->stk_len = 11809, th->stk_max = 10247 | realloc ptr = 65a590 | o | TestThread.rb:378:in `test_s_abort_on_exception=': boom (RuntimeError) | from TestThread.rb:377:in `initialize' | from TestThread.rb:377:in `new' | from TestThread.rb:377:in `test_s_abort_on_exception=' | from /usr/local/lib/ruby/site_ruby/runit/testcase.rb:41:in `send' | from /usr/local/lib/ruby/site_ruby/runit/testcase.rb:41:in `run_bare' | from /usr/local/lib/ruby/site_ruby/runit/testresult.rb:83:in `run' | from /usr/local/lib/ruby/site_ruby/runit/testcase.rb:35:in `run' | from /usr/local/lib/ruby/site_ruby/runit/testsuite.rb:15:in `run' | from /usr/local/lib/ruby/site_ruby/runit/testsuite.rb:14:in `each' | from /usr/local/lib/ruby/site_ruby/runit/testsuite.rb:14:in `run' | from /usr/local/lib/ruby/site_ruby/runit/cui/testrunner.rb:27:in `run' | from ./../rubicon_tests.rb:238:in `handleTests' | from TestThread.rb:524 | th->stk_ptr = 0, th->stk_len = 10261, th->stk_max = 11373 | o | TestThread.rb:377: [BUG] Segmentation fault | ruby 1.7.3 (2002-09-17) [mips-sysv4.2MP] | ABORT instruction (core dumped) っとなります。いろいろと持って帰るのを忘れたので不正確な情報 で申し訳ないのですが、ソースの該当箇所は以下で、 | static void | rb_thread_save_context(th) | rb_thread_t th; | { | VALUE *pos; | int len; | static VALUE tval; | | len = ruby_stack_length(&pos); | th->stk_len = 0; | th->stk_pos = (rb_gc_stack_start th->stk_max) { | REALLOC_N(th->stk_ptr, VALUE, len); | th->stk_max = len; | } | th->stk_len = len; | FLUSH_REGISTER_WINDOWS; | MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); 落ちるのは MEMCPY のところです。上記の結果出力で、落ちる直前に | th->stk_ptr = 0, th->stk_len = 10261, th->stk_max = 11373 っとあるので、stk_ptr = 0 で、REALLOC_N() されない条件がある ようです。 以下の暫定対処で落ちなくなるのまでは確認しました。 --- ruby/eval.c Tue Sep 17 22:52:45 2002 +++ ruby-1.7/eval.c Thu Sep 19 05:14:49 2002 @@ -7598,7 +7598,11 @@ th->stk_len = 0; th->stk_pos = (rb_gc_stack_start th->stk_max) { + if (th->stk_ptr == 0) { + th->stk_ptr = ALLOC_N(VALUE, len); + th->stk_max = len; + } + else if (len > th->stk_max) { REALLOC_N(th->stk_ptr, VALUE, len); th->stk_max = len; } -- 新井康司 (Koji Arai)