Bug #1676
closedonly last "return" is traced by set_trace_func
Description
=begin
複数ある 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", "", 1, :foo, #Binding:0xb94d80, Object]
["return", "", 1, :foo, #Binding:0xb94a40, Object]
["call", "", 1, :foo, #Binding:0xb947a0, Object]
== disasm: <RubyVM::InstructionSequence:@>==========
0000 trace 1 ( 1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject :foo
0008 putiseq foo
0010 send :"core#define_method", 3, nil, 0,
0016 pop
0017 trace 1 ( 5)
0019 putnil
0020 putobject false
0022 send :foo, 1, nil, 8,
0028 pop
0029 trace 1 ( 6)
0031 putnil
0032 putobject true
0034 send :foo, 1, nil, 8,
0040 leave
== disasm: <RubyVM::InstructionSequence:foo@>=================
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] a
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)
=end
Updated by yugui (Yuki Sonoda) over 15 years ago
- Category set to YARV
- Assignee set to ko1 (Koichi Sasada)
- Priority changed from 3 to 5
- Target version set to 1.9.2
=begin
=end
Updated by mark-moseley (Mark Moseley) over 15 years ago
=begin
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.
=end
Updated by rogerdpack (Roger Pack) over 15 years ago
=begin
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.
=end
Updated by mame (Yusuke Endoh) over 15 years ago
=begin
Hi,
2009/08/09 1:29 に Mark Moseleyredmine@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
=end
Updated by mame (Yusuke Endoh) over 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r24579.
=end
Updated by mame (Yusuke Endoh) over 15 years ago
- Status changed from Closed to Open
- Priority changed from 5 to 3
=begin
直した直後に気がつきましたが、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
=end
Updated by mame (Yusuke Endoh) over 15 years ago
- Status changed from Open to Closed
=begin
Applied in changeset r24581.
=end
Updated by mame (Yusuke Endoh) over 15 years ago
- Status changed from Closed to Open
=begin
テストを追加した際、間違って close してしまいました。
eval("return") はまだ修正していません。
何度もすみません。
=end
Updated by wanabe (_ wanabe) over 15 years ago
=begin
遠藤さん、ありがとうございます。Mark さんへの説明も重ね重ねありがとうございます。
自明のことかもしれませんが、自分で困ったので念のため
proc {return}.call のようなときにも問題があることを報告させていただきます。
=end
Updated by mame (Yusuke Endoh) over 14 years ago
- Status changed from Open to Closed
=begin
遠藤です。
残っていた課題も、ささださんが知らぬ間に直してくれていた
(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
=end