Bug #1676
only last "return" is traced by set_trace_func
| Status: | Closed | Start date: | 06/22/2009 | |
|---|---|---|---|---|
| Priority: | Low | Due date: | ||
| Assignee: | % Done: | 100% |
||
| Category: | YARV | |||
| Target version: | 1.9.2 | |||
| ruby -v: | ruby 1.9.2dev (2009-06-21 trunk 23809) [i386-mingw32] |
Description
複数ある return のうち最後ではないものでメソッドの処理が終わったとき
set_trace_func の "return" イベントが起こりません。
$ ruby -ve '
set_trace_func(proc{|*a|p a if a[0] == "call" || a[0] == "return"})
iseq = RubyVM::InstructionSequence.compile(<<EOS)
def foo(a)
return if a
return
end
foo(false)
foo(true)
EOS
iseq.eval
puts iseq.disasm
'
ruby 1.9.2dev (2009-06-21 trunk 23809) [i386-mingw32]
["call", "<compiled>", 1, :foo, #<Binding:0xb94d80>, Object]
["return", "<compiled>", 1, :foo, #<Binding:0xb94a40>, Object]
["call", "<compiled>", 1, :foo, #<Binding:0xb947a0>, Object]
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace 1 ( 1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject :foo
0008 putiseq foo
0010 send :"core#define_method", 3, nil, 0, <ic>
0016 pop
0017 trace 1 ( 5)
0019 putnil
0020 putobject false
0022 send :foo, 1, nil, 8, <ic>
0028 pop
0029 trace 1 ( 6)
0031 putnil
0032 putobject true
0034 send :foo, 1, nil, 8, <ic>
0040 leave
== disasm: <RubyVM::InstructionSequence:foo@<compiled>>=================
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] a<Arg>
0000 trace 8 ( 1)
0002 trace 1 ( 2)
0004 getlocal a
0006 branchunless 12
0008 jump 10
0010 putnil
0011 leave
0012 putnil
0013 trace 16 ( 1)
0015 leave ( 2)
Associated revisions
* compile.c (NODE_RETURN): fire return event at explicit return.
[ruby-dev:38701]
* test/ruby/test_settracefunc.rb (test_return, test_return2): add two
tests for [ruby-dev:38701] and [ruby-core:24463].
History
Updated by Yuki Sonoda over 2 years ago
- Category set to YARV
- Assignee set to Koichi Sasada
- Priority changed from Low to High
- Target version set to 1.9.2
Updated by Mark Moseley over 2 years ago
Patch to fix this:
--- compile.c (revision 24476)
+++ compile.c (working copy)
@@ -2959,6 +2959,8 @@
COMPILE_(ret, "BLOCK body", node->nd_head,
(node->nd_next == 0 && poped == 0) ? 0 : 1);
node = node->nd_next;
+ if (node)
+ iseq->compile_data->last_line = nd_line(node);
}
if (node) {
COMPILE_(ret, "BLOCK next", node->nd_next, poped);
This is probably not the best solution, though. It appears to me that there might be other problems lurking in iseq_compile_each() after any "node = node->nd_next" statement. I think that probably a macro that both goes to the next node, and resets the line number, (and maybe also resets type) is appropriate, but I haven't investigated this in depth.
Updated by Roger Pack over 2 years ago
As a note, this is fixed by a patch discussed here http://github.com/mark-moseley/ruby-debug/issues/#issue/1/comment/36731 If that's any help.
Updated by Yusuke Endoh over 2 years ago
Hi,
2009/08/09 1:29 に Mark Moseley<redmine@ruby-lang.org> さんは書きました:
> Patch to fix this:
>
> --- compile.c (revision 24476)
> +++ compile.c (working copy)
> @@ -2959,6 +2959,8 @@
> COMPILE_(ret, "BLOCK body", node->nd_head,
> (node->nd_next == 0 && poped == 0) ? 0 : 1);
> node = node->nd_next;
> + if (node)
> + iseq->compile_data->last_line = nd_line(node);
> }
> if (node) {
> COMPILE_(ret, "BLOCK next", node->nd_next, poped);
wanabe reports an unexpected behavior in which return event should be
fired but not when foo(true) is called. This will be fixed by the
following patch:
Index: compile.c
===================================================================
--- compile.c (revision 24578)
+++ compile.c (working copy)
@@ -4205,6 +4205,7 @@
if (is->type == ISEQ_TYPE_METHOD) {
add_ensure_iseq(ret, iseq, 1);
+ ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
ADD_INSN(ret, nd_line(node), leave);
ADD_ADJUST_RESTORE(ret, splabel);
Your patch fixes line number of return event. Indeed, the line number
is wrong, which is another problem.
In place of ko1, I'll checking both the problem and [ruby-core:24463]
with your whole patch (http://gist.github.com/166330) later.
Anyway, thank you for your patch.
--
Yusuke ENDOH <mame@tsg.ne.jp>
Updated by Yusuke Endoh over 2 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r24579.
Updated by Yusuke Endoh over 2 years ago
- Status changed from Closed to Open
- Priority changed from High to Low
直した直後に気がつきましたが、eval("return") の場合に問題が残ります。
$ ./ruby -e '
set_trace_func(proc{|*a| p a if a[0] == "call" || a[0] == "return"})
def foo
eval("return")
end
foo
'
["call", "-e", 3, :foo, #<Binding:0x8224b44>, Object]
直すのが面倒そうなのと、あまり問題にならなさそうなので
報告だけして後回しにします。
--
Yusuke ENDOH <mame@tsg.ne.jp>
Updated by Yusuke Endoh over 2 years ago
- Status changed from Open to Closed
Applied in changeset r24581.
Updated by Yusuke Endoh over 2 years ago
- Status changed from Closed to Open
テストを追加した際、間違って close してしまいました。
eval("return") はまだ修正していません。
何度もすみません。
Updated by _ wanabe over 2 years ago
遠藤さん、ありがとうございます。Mark さんへの説明も重ね重ねありがとうございます。
自明のことかもしれませんが、自分で困ったので念のため
proc {return}.call のようなときにも問題があることを報告させていただきます。
Updated by Yusuke Endoh almost 2 years ago
- Status changed from Open to Closed
遠藤です。
残っていた課題も、ささださんが知らぬ間に直してくれていた
(r26395) ので close します。
$ ./ruby -e '
set_trace_func(proc{|*a| p a if a[0] == "call" || a[0] == "return"})
def foo
eval("return")
end
foo
'
["call", "-e", 3, :foo, #<Binding:0x822a8f0>, Object]
["return", "-e", 4, :foo, #<Binding:0x822a4cc>, Object]
$ ./ruby -e '
set_trace_func(proc{|*a| p a if a[0] == "call" || a[0] == "return"})
def foo
proc {return}.call
end
foo
'
["call", "-e", 3, :foo, #<Binding:0x822a83c>, Object]
["return", "-e", 4, :foo, #<Binding:0x822a3dc>, Object]
--
Yusuke Endoh <mame@tsg.ne.jp>