history

青木日記 RSS

<前の日 | この月 | 次の日>

2006-02-20

delegate.rb

どうしてこれが動かないのかと思ったら……

 
require 'delegate'
 
class A
end
 
class B < DelegateClass(A)
  def initialize
    super A.new
  end
end
 
class C < B
  def m
    puts "C, OK"
  end
end
 
C.new.funcall(:m)   # NoMethodError???

funcall を delegate.rb がフックしてて、 勝手に NoMethodError にしてくれてました。 ついでに inspect までデレゲートしてくれたおかげでデバッグしにくいのなんのって。 Rails の奥底でこれにはまったおかげで 4 時間もかかったよ。 知らねーうちにレシーバがすりかわってる (ように見える) んだもんな。 しかもデレゲート先と引数が偶然同じだったがために余計なところをえんえんひきずりまわされてさ。 この仕様はつくづく許しがたい。

(07:48)

Rails on YARV

YARV で Rails。 なんとか最初の自動生成は通った (通した) んだが、 WEBrick を起動した瞬間に落ちた。 このさい WEBrick をあきらめて CGI でなんとかするほうが早いかな。

さて Rails で CGI はどーすんのかなー。

(08:04)

Rails on YARV (2)

public/dispatch.cgi という怪しげなファイルを発見!

/var/www/rails/testsite % ./public/dispatch.cgi                 aamine@serenade
DBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:159:in `finish'"
DBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:137:in `go'"
DBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:132:in `continue'"
 
……略……
 
c:0005 p:-001 s:0007 b:0007 l:0006 d:0006 FINISH i:-        s:         -
c:0004 p:-001 s:0006 b:0006 l:0005 d:0005 CFUNC  i:require  s:         -
c:0003 p:0037 s:0003 b:0003 l:-861 d:-861 TOP    i:<main>   s:         -
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:-        s:         -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:-        s:         -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2006-02-14) [x86_64-linux]
 

そんなお約束なー!

(08:08)

Rails on YARV (3)

問題の個所を切り出しただけでは再現しない。 嫌だなあ。つくづく嫌だなあ。

(08:18)

Rails on YARV (4)

わかったよー、追うよ追いますよ!

/var/www/rails/testsite % gdb -c core /usr/local/pkg/yarv/bin/ruby
ずばっと略
 
(gdb) bt
#0  0x0000002a95d8fdd0 in raise () from /lib/libc.so.6
#1  0x0000002a95d91280 in abort () from /lib/libc.so.6
#2  0x0000002a9569d1b5 in rb_bug (fmt=0x2a9573d021 "Segmentation fault")
    at error.c:171
#3  0x0000002a956f7ae0 in sigsegv (sig=11) at signal.c:467
#4  <signal handler called>
#5  th_invoke_proc (th=0x55d1d0, proc=0x11a7d80, self=0, argc=1,
    argv=0x2a96102550) at vm.c:666
#6  0x0000002a9571e984 in proc_call (argc=1, argv=0x2a96102550,
    procval=182929376352) at yarv.h:49
#7  0x0000002a9571c3bb in call_cfunc (func=0x2a9571e940 <proc_call>,
    recv=182929376352, len=0, argc=5624272, argv=0x0) at call_cfunc.h:24
#8  0x0000002a9571a445 in th_eval (th=0x55d1d0, initial=0) at insns.def:1253
#9  0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449
#10 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929388432,
    id=182902709320, oid=182906266960, argc=2, argv=0x2a96102468,
    body=0xc4d580, nosuper=0) at vm.c:425
#11 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929388432,
    mid=3977, argc=2, argv=0x2a96102438, scope=1) at yarv.h:49
#12 0x0000002a9571a5b0 in th_eval (th=0x55d1d0, initial=0) at vm.c:1149
#13 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449
#14 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929400152,
    id=182902709320, oid=182906266960, argc=2, argv=0x2a961022f8,
    body=0xc4d580, nosuper=0) at vm.c:425
#15 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929400152,
    mid=3977, argc=2, argv=0x2a961022c8, scope=1) at yarv.h:49
#16 0x0000002a9571a5b0 in th_eval (th=0x55d1d0, initial=0) at vm.c:1149
#17 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449
#18 0x0000002a95717df6 in th_invoke_yield (th=0x55d1d0, argc=1,
    argv=0xfaffff21) at vm.c:640
#19 0x0000002a956a40b6 in rb_yield_0 (val=182929495112, self=0, klass=0,
    flags=-1780884408, avalue=-1777326768) at yarv.h:49
#20 0x0000002a9568fbe0 in rb_ary_each (ary=182929495392) at array.c:1147
#21 0x0000002a9571c3c4 in call_cfunc (func=0x2a9568fb70 <rb_ary_each>,
    recv=182929495392, len=0, argc=5624272, argv=0x0) at call_cfunc.h:27
#22 0x0000002a9571a445 in th_eval (th=0x55d1d0, initial=0) at insns.def:1253
#23 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449
#24 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929403472,
    id=182902709320, oid=182906266960, argc=2, argv=0x2a961021c0,
    body=0xc4d580, nosuper=0) at vm.c:425
#25 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929403472,
    mid=3977, argc=2, argv=0x2a96102190, scope=1) at yarv.h:49
 
以下略

とりあえず一番上のフレームを見てみる。

(gdb) f 6
#6  0x0000002a9571e984 in proc_call (argc=1, argv=0x2a96102550,
    procval=182929376352) at yarv.h:49
49      {
(gdb) list
44          return theYarvVM;
45      }
46
47      static inline yarv_thread_t *
48      yarv_get_current_running_thread(void)
49      {
50          return yarvCurrentThread;
51      }
52
53      static inline void
(gdb) p yarvCurrentThread
$1 = (yarv_thread_t *) 0x55d1d0
(gdb) p *$1
$2 = {self = 182906065688, vm = 0x55d0a0, stack = 0x2a96102010,
  stack_size = 131072, cfp = 0x2a96200e90, safe_level = 0, state = 0,
  passed_block = 0x0, top_local_tbl = 0x0, base_block = 0x0, local_lfp = 0x0,
  local_svar = 0, thread_id = 182904806112, status = THREAD_RUNNABLE,
  priority = 0, native_thread_data = {dummy = 0}, thgroup = 182906060288,
  value = 0, wait_thread_value = 0, errinfo = 4, throwed_errinfo = 0,
  interrupt_flag = 0, tag = 0x7fbfffae00, parse_in_eval = 0,
  local_storage = 0xe8a8c0, signal_queue = {buff = {0 <repeats 16 times>},
    head = 0, tail = 0}, signal_thread_list = 0x0, first_proc = 0,
  first_args = 0, machine_stack_start = 0x7fbffff600,
  machine_stack_end = 0x7fbfffc560, machine_regs = {{__jmpbuf = {5624568,
        5624272, 5624272, 4, 182897364680, 1, 548682057072, 182895908384},
      __mask_was_saved = 0, __saved_mask = {__val = {0 <repeats 16 times>}}}},
  stat_insn_usage = 0, method_missing_reason = 0, abort_on_exception = 0}

GET_THREAD() の中に入っちゃってるな。 これは意味なさそう。 proc_call() の引数を見たほうがいいか。

(gdb) p 0x2a96102550
$3 = 182906266960
(gdb) p (VALUE*)$3
$4 = (long unsigned int *) 0x2a96102550
(gdb) p *$4
$5 = 182929375032
(gdb) rp $5
T_STRING
$6 = {basic = {flags = 7, klass = 182906235808}, len = 54,
  ptr = 0x12eb390 "{\"controller\" => controller_value, \"action\" => \"wsdl\"}", aux = {capa = 62, shared = 62}}
(gdb) rp 182929376352
T_DATA
$7 = {basic = {flags = 18, klass = 182906068888},
  dmark = 0x2a9571e860 <proc_mark>, dfree = 0x2a9571e840 <proc_free>,
  data = 0x11a7d80}
(gdb) p $7.data
$8 = (void *) 0x11a7d80
(gdb) p (yarv_proc_t*)$8
$9 = (struct {...} *) 0x11a7d80
(gdb) p *$9
$10 = {block = {self = 0, lfp = 0x0, dfp = 0x0, iseq = 0x0, proc = 0},
  envval = 0, blockprocval = 0, safe_level = 0, is_lambda = 0,
  special_cref_stack = 0x0}

呼ぼうとした Proc の実体が初期化されてないのか……?

(08:30)

Rails on YARV (5)

おーし、

require 'rubygems'
require_gem 'actionpack'
 
ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/service.wsdl', :action => 'wsdl'
  map.connect ':controller/:action/:id'
end

で再現。あとはどこまで短縮できるかだ。

(09:01)

Rails on YARV (6)

特定完了

~/c/yarv/REPOS/actionpack % /usr/local/pkg/yarv/bin/ruby -e 'Proc.new{}.dup.call'
DBG> : "-e:1:in `<main>'"
-- stack frame ------------
0x2a96102010 (0000): 00000001
0x2a96102018 (0001): 00000004
0x2a96102020 (0002): 2a960cf298
0x2a96102028 (0003): 2a960cf248
0x2a96102030 (0004): 00000001 <- lfp <- dfp
-- control frame ----------
c:0004 p:-001 s:0005 b:0005 l:0004 d:0004 CFUNC  i:call     s:         -
c:0003 p:0025 s:0003 b:0003 l:-815 d:-815 TOP    i:<main>   s:
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:-        s:         -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:-        s:         -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2006-02-14) [x86_64-linux]
 
zsh: 24815 abort (core dumped)  /usr/local/pkg/yarv/bin/ruby -e 'Proc.new{}.dup.call'

(09:53)

Rails on YARV (8)

むっ?! よく見たら WEBrick のときの SEGV も同じじゃないか。 ということはこのバグが直れば WEBrick で動くのかも。

(09:57)

Rails on YARV (9)

そうか……ということはこれでも落ちるだろうなあ。

~/c/yarv % ./ruby -e 'Proc.allocate.call'
DBG> : "-e:1:in `<main>'"
-- stack frame ------------
0x2a96102010 (0000): 00000001
0x2a96102018 (0001): 00000004
0x2a96102020 (0002): 2a960cf4a0
0x2a96102028 (0003): 2a960cf478
0x2a96102030 (0004): 00000001 <- lfp <- dfp
-- control frame ----------
c:0004 p:-001 s:0005 b:0005 l:0004 d:0004 CFUNC  i:call     s:         -
c:0003 p:0019 s:0003 b:0003 l:-811 d:-811 TOP    i:<main>   s:         -
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:-        s:         -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:-        s:         -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2006-02-14) [x86_64-linux]
 
zsh: 24828 abort (core dumped)  ./ruby -e 'Proc.allocate.call'

やはり。ということは、こんなのとか、

~/c/yarv % ./ruby -e 'p YARVCore::InstructionSequence.allocate'
DBG> : "-e:1:in `p'"
DBG> : "-e:1:in `<main>'"
-- stack frame ------------
0x2a95ee2010 (0000): 00000001
0x2a95ee2018 (0001): 00000004
0x2a95ee2020 (0002): 2a95eaf450
0x2a95ee2028 (0003): 2a95ede408
0x2a95ee2030 (0004): 2a95eaf428
0x2a95ee2038 (0005): 00000001
0x2a95ee2040 (0006): 00000001 <- lfp <- dfp
-- control frame ----------
c:0005 p:-001 s:0007 b:0007 l:0006 d:0006 CFUNC  i:inspect  s:         -
c:0004 p:-001 s:0006 b:0006 l:0005 d:0005 CFUNC  i:p        s:         -
c:0003 p:0022 s:0003 b:0003 l:-093 d:-093 TOP    i:<main>   s:         -
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:-        s:         -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:-        s:         -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2006-02-14) [x86_64-linux]

こんなのとか、

~/c/yarv % ./ruby -e 'p YARVCore::VM.allocate.eval(YARVCore::InstructionSequence.allocate)'
DBG> : "-e:1:in `eval'"
DBG> : "-e:1:in `<main>'"
-- stack frame ------------
0x2a95ee2010 (0000): 00000001
0x2a95ee2018 (0001): 00000004
0x2a95ee2020 (0002): 2a95eaf2e8
0x2a95ee2028 (0003): 2a95ede408
0x2a95ee2030 (0004): 2a95eaf2c0
0x2a95ee2038 (0005): 2a95eaf298
0x2a95ee2040 (0006): 00000001
0x2a95ee2048 (0007): 00000001
0x2a95ee2050 (0008): 00000001 <- lfp <- dfp
-- control frame ----------
c:0006 p:-001 s:0009 b:0009 l:0008 d:0008 TOP    i:(null)   s:         -
c:0005 p:-001 s:0008 b:0008 l:0007 d:0007 FINISH i:-        s:         -
c:0004 p:-001 s:0007 b:0007 l:0006 d:0006 CFUNC  i:eval     s:         -
c:0003 p:0037 s:0004 b:0003 l:-083 d:-083 TOP    i:<main>   s:         -
c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:-        s:         -
c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:-        s:         -
---------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2006-02-14) [x86_64-linux]

こんなのもヤバげということに……

~/c/yarv % ./ruby -e 'p eval("", YARVCore::VM::Binding.allocate)'
-e:1:in `eval': -e:1:in `eval': wrong argument type false (expected Data) (TypeError)
        from -e:1:in `<main>'
 
~/c/yarv % ./ruby -e 'eval("", binding().dup)'
-e:1:in `eval': -e:1:in `eval': wrong argument type false (expected Data) (TypeError)
        from -e:1:in `<main>'

(10:23)

Rails on YARV (10)

/var/www/rails/testsite % /usr/local/pkg/yarv/bin/ruby script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2006-02-20 10:40:23] INFO  WEBrick 1.3.1
[2006-02-20 10:40:23] INFO  ruby 1.9.0 (2006-02-14) [x86_64-linux]
[2006-02-20 10:40:23] INFO  WEBrick::HTTPServer#start: pid=25032 port=3000

動いちゃったよ……。

(10:46)

本日のツッコミ(全2件) [ツッコミを入れる]
Emma (2006-07-17 23:23)

Great work!
[url=http://mvjurjdl.com/xdfk/jcmb.html]My homepage[/url] | [url=http://bwhfucro.com/vuab/utgv.html]Cool site[/url]

Olga (2006-07-17 23:25)

Thank you!
http://mvjurjdl.com/xdfk/jcmb.html | http://zarpjrwc.com/bszi/fzya.html

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|

Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved. LIRS