Project

General

Profile

Bug #1676

only last "return" is traced by set_trace_func

Added by wanabe (_ wanabe) over 9 years ago. Updated almost 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.2dev (2009-06-21 trunk 23809) [i386-mingw32]
Backport:
[ruby-dev:38701]

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(<", 1, :foo, #Binding:0xb94d80, Object]
["return", "", 1, :foo, #Binding:0xb94a40, Object]
["call", "", 1, :foo, #Binding:0xb947a0, Object]
== disasm: RubyVM::InstructionSequence:<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,
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@<compiled>=================
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

History

#1

Updated by yugui (Yuki Sonoda) over 9 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

#2

Updated by mark-moseley (Mark Moseley) over 9 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

#3

Updated by rogerdpack (Roger Pack) over 9 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

#4

Updated by mame (Yusuke Endoh) over 9 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

#5

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r24579.
=end

#6

Updated by mame (Yusuke Endoh) over 9 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

#7

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Open to Closed

=begin
Applied in changeset r24581.
=end

#8

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Closed to Open

=begin
テストを追加した際、間違って close してしまいました。
eval("return") はまだ修正していません。
何度もすみません。
=end

#9

Updated by wanabe (_ wanabe) over 9 years ago

=begin
遠藤さん、ありがとうございます。Mark さんへの説明も重ね重ねありがとうございます。
自明のことかもしれませんが、自分で困ったので念のため
proc {return}.call のようなときにも問題があることを報告させていただきます。
=end

#10

Updated by mame (Yusuke Endoh) almost 9 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

Also available in: Atom PDF