[Bug #1676] only last "return" is traced by set_trace_func

Bug #1676: only last “return” is traced by set_trace_func
http://redmine.ruby-lang.org/issues/show/1676

e$B5/I<<Te(B: _ wanabe
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Low
ruby -v: ruby 1.9.2dev (2009-06-21 trunk 23809) [i386-mingw32]

e$BJ#?t$"$ke(B return
e$B$N$&$A:G8e$G$O$J$$$b$N$G%a%=%C%I$N=hM}$,=*$o$C$?$H$-e(B
set_trace_func e$B$Ne(B “return” e$B%$%Y%s%H$,5/$3$j$^$;$s!#e(B

$ 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)

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Mark M.)

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.

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Roger P.)

As a note, this is fixed by a patch discussed here
Pull requests · mark-moseley/ruby-debug · GitHub
If that’s any help.

http://redmine.ruby-lang.org/issues/show/1676

Hi,

2009/08/09 1:29 e$B$Ke(B Mark M.[email protected]
e$B$5$s$O=q$-$^$7$?e(B:

}
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 (gist:166330 · GitHub) later.

Anyway, thank you for your patch.

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Closede$B$+$ie(BOpene$B$KJQ99e(B
e$BM%@hEYe(B Highe$B$+$ie(BLowe$B$KJQ99e(B

e$BD>$7$?D>8e$K5$$,$D$-$^$7$?$,!"e(Beval(“return”)
e$B$N>l9g$KLdBj$,;D$j$^$9!#e(B

$ ./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]

e$BD>$9$N$,LLE]$=$&$J$N$H!“$”$^$jLdBj$K$J$i$J$5$=$&$J$N$Ge(B
e$BJs9p$@$1$7$F8e2s$7$K$7$^$9!#e(B


Yusuke ENDOH [email protected]

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r24579.

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Closede$B$+$ie(BOpene$B$KJQ99e(B

e$B%F%9%H$rDI2C$7$?:]!"4V0c$C$Fe(B close e$B$7$F$7$^$$$^$7$?!#e(B
eval(“return”) e$B$O$^$@=$@5$7$F$$$^$;$s!#e(B
e$B2?EY$b$9$_$^$;$s!#e(B

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B

Applied in changeset r24581.

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by _ wanabe)

e$B1sF#$5$s!“$”$j$,$H$&$4$6$$$^$9!#e(BMark
e$B$5$s$X$N@bL@$b=E$M=E$M$“$j$,$H$&$4$6$$$^$9!#e(B
e$B<+L@$N$3$H$+$b$7$l$^$;$s$,!”<+J,$G:$$C$?$N$GG0$N$?$ae(B
proc {return}.call
e$B$N$h$&$J$H$-$K$bLdBj$,$"$k$3$H$rJs9p$5$;$F$$$?$@$-$^$9!#e(B

http://redmine.ruby-lang.org/issues/show/1676

e$B%A%1%C%He(B #1676 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B

e$B1sF#$G$9!#e(B

e$B;D$C$F$$$?2]Bj$b!"$5$5$@$5$s$,CN$i$L4V$KD>$7$F$/$l$F$$$?e(B
(r26395) e$B$N$Ge(B close e$B$7$^$9!#e(B

$ ./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 E. [email protected]

http://redmine.ruby-lang.org/issues/show/1676