[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]