[#20227] dyna_vars problem? — Tanaka Akira <akr@...17n.org>

しばらく前から、稀に Ruby が core を吐くという問題を追いかけているので

15 messages 2003/05/19
[#20234] Re: dyna_vars problem? — matz@... (Yukihiro Matsumoto) 2003/05/19

まつもと ゆきひろです

[#20236] Re: dyna_vars problem? — Tanaka Akira <akr@...17n.org> 2003/05/19

In article <1053363181.529491.30320.nullmailer@picachu.netlab.jp>,

[ruby-dev:20227] dyna_vars problem?

From: Tanaka Akira <akr@...17n.org>
Date: 2003-05-19 12:42:07 UTC
List: ruby-dev #20227
しばらく前から、稀に Ruby が core を吐くという問題を追いかけているので
すが、それに関して質問があります。

まず、次のような表明は正しいでしょうか?

Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.433
diff -u -r1.433 eval.c
--- eval.c	19 May 2003 05:41:07 -0000	1.433
+++ eval.c	19 May 2003 12:17:37 -0000
@@ -12,6 +12,7 @@
 
 **********************************************************************/
 
+#include <assert.h>
 #include "ruby.h"
 #include "node.h"
 #include "env.h"
@@ -8423,6 +8424,9 @@
 
     /* context switch */
     if (curr == curr_thread) {
+        struct RVarmap * volatile v;
+        for (v = curr->dyna_vars; v; v = v->next)
+          assert(TYPE(v) == T_VARMAP);
 	if (THREAD_SAVE_CONTEXT(curr)) {
 	    return;
 	}

たぶん、正しいと思うんですが、正しいとすると、これを破るようなスクリプ
トが書けます。後につけますが、それを実行すると、上記の表明が次のように
破れることがあります。

(gdb) run -d tst
Starting program: /tmp/z/ruby/ruby -d tst
ruby: eval.c:8429: rb_thread_schedule: Assertion `rb_type((VALUE)(v)) == 0x3d' failed.

Program received signal SIGABRT, Aborted.
0x40091a51 in kill () from /lib/libc.so.6
(gdb) up
#1  0x40091872 in raise () from /lib/libc.so.6
(gdb) 
#2  0x40092986 in abort () from /lib/libc.so.6
(gdb) 
#3  0x4008bae9 in __assert_fail () from /lib/libc.so.6
(gdb) 
#4  0x08063013 in rb_thread_schedule () at eval.c:8429
8429              assert(TYPE(v) == T_VARMAP);
(gdb) p v
$1 = (struct RVarmap *) 0x401c39ec
(gdb) p *v
$2 = {super = {flags = 0, klass = 1075590680}, id = 0, val = 0, next = 0x0}
(gdb) p curr->dyna_vars
$3 = (struct RVarmap *) 0x401c39ec
(gdb) where
#0  0x40091a51 in kill () from /lib/libc.so.6
#1  0x40091872 in raise () from /lib/libc.so.6
#2  0x40092986 in abort () from /lib/libc.so.6
#3  0x4008bae9 in __assert_fail () from /lib/libc.so.6
#4  0x08063013 in rb_thread_schedule () at eval.c:8429
#5  0x0806388e in rb_thread_kill (thread=1075595600) at eval.c:8757
#6  0x0805b2e1 in rb_call0 (klass=1075471816, recv=1075595600, id=5969, oid=5969, argc=0, argv=0x0, body=0x401a62e4, 
    nosuper=1) at eval.c:4647
#7  0x0805bcb6 in rb_call (klass=1075471816, recv=1075595600, mid=5969, argc=0, argv=0x0, scope=0) at eval.c:4986
#8  0x08056c71 in rb_eval (self=1075595780, n=0x401e239c) at eval.c:2926
#9  0x0805647c in rb_eval (self=1075595780, n=0x401e20f4) at eval.c:2793
#10 0x0805b8a9 in rb_call0 (klass=1075494176, recv=1075595780, id=14849, oid=14849, argc=0, argv=0xbfff22a4, 
    body=0x401e20f4, nosuper=0) at eval.c:4897
#11 0x0805bcb6 in rb_call (klass=1075494176, recv=1075595780, mid=14849, argc=1, argv=0xbfff22a0, scope=1) at eval.c:4986
#12 0x08056e6c in rb_eval (self=1075595780, n=0x401fa0a0) at eval.c:2940
#13 0x08055d61 in rb_eval (self=1075595780, n=0x401f9f60) at eval.c:2651
#14 0x0805b8a9 in rb_call0 (klass=1075705060, recv=1075595780, id=14825, oid=14825, argc=0, argv=0xbfff2ea4, 
    body=0x401f9f60, nosuper=0) at eval.c:4897
#15 0x0805bcb6 in rb_call (klass=1075705060, recv=1075595780, mid=14825, argc=1, argv=0xbfff2ea0, scope=1) at eval.c:4986
#16 0x08056e6c in rb_eval (self=1075595780, n=0x401fb964) at eval.c:2940
#17 0x0805b8a9 in rb_call0 (klass=1075705060, recv=1075595780, id=2937, oid=2937, argc=0, argv=0xbfff38b4, 
    body=0x401fb964, nosuper=0) at eval.c:4897
#18 0x0805bcb6 in rb_call (klass=1075705060, recv=1075595780, mid=2937, argc=5, argv=0xbfff38a0, scope=1) at eval.c:4986
#19 0x0805bf59 in rb_funcall2 (recv=1075595780, mid=2937, argc=5, argv=0xbfff38a0) at eval.c:5069
#20 0x0805e443 in rb_obj_call_init (obj=1075595780, argc=5, argv=0xbfff38a0) at eval.c:6101
#21 0x0807eaab in rb_class_new_instance (argc=5, argv=0xbfff38a0, klass=1075705060) at object.c:761
#22 0x0805b2ae in rb_call0 (klass=1075494136, recv=1075705060, id=7209, oid=3337, argc=5, argv=0xbfff38a0, 
    body=0x401aab64, nosuper=1) at eval.c:4641
#23 0x0805bcb6 in rb_call (klass=1075494136, recv=1075705060, mid=7209, argc=5, argv=0xbfff38a0, scope=0) at eval.c:4986
#24 0x08056c71 in rb_eval (self=1075595820, n=0x401b37a4) at eval.c:2926
#25 0x08057872 in rb_eval (self=1075595820, n=0x401b3740) at eval.c:3120
#26 0x0805b8a9 in rb_call0 (klass=1075679300, recv=1075595820, id=13257, oid=13257, argc=0, argv=0x0, body=0x401b3740, 
    nosuper=0) at eval.c:4897
#27 0x0805bcb6 in rb_call (klass=1075679300, recv=1075595820, mid=13257, argc=0, argv=0x0, scope=2) at eval.c:4986
#28 0x08056edc in rb_eval (self=1075595820, n=0x401b3bb4) at eval.c:2946
#29 0x0805642d in rb_eval (self=1075595820, n=0x401b3a88) at eval.c:2786
#30 0x0805b8a9 in rb_call0 (klass=1075679300, recv=1075595820, id=5945, oid=5945, argc=0, argv=0x0, body=0x401b3a88, 
    nosuper=0) at eval.c:4897
#31 0x0805bcb6 in rb_call (klass=1075679300, recv=1075595820, mid=5945, argc=0, argv=0x0, scope=0) at eval.c:4986
---Type <return> to continue, or q <return> to quit---

flags が 0 であるところからして、これは開放されちゃってるんじゃないか
と思うんですが、これって意図されているんでしょうか?

#!/usr/bin/env ruby

require 'open-uri'

module Enumerable
  def concurrent_map(max_threads=2)
    arr = self.to_a
    queue = (0...arr.length).to_a

    max_threads = arr.length if arr.length < max_threads

    threads = []
    max_threads.times {
      threads << Thread.new {
        while i = queue.shift
          arr[i] = yield arr[i]
        end
      }
    }

    threads.each {|t| t.join }
    arr
  end
end

def main
 Array.new(4).concurrent_map {
    page = URI.parse("http://www.ruby-lang.org/ja/").read
 }
end

main

# 再現しない場合、もしかしたら、Array.new(4) の 4 や
# max_threads=2 の 2 を大きくすると再現するのかも知れません。
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread

Prev Next