mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix TracePoint for nested iseq loaded from binary [Bug#14702]
When loading iseq from binary while a TracePoint is on, we need to recompile instructions to their "trace_" variant. Before this commit we only recompiled instructions in the top level iseq, which meant that TracePoint was malfunctioning for code inside module/class/method definitions. * compile.c: Move rb_iseq_init_trace to rb_ibf_load_iseq_complete. It is called on all iseqs during loading. * test_iseq.rb: Test that tracepoints fire within children iseq when using load_from_binary. This patch is from: Alan Wu <XrXr@users.noreply.github.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b11b804f8f
commit
09821dd2a5
2 changed files with 70 additions and 10 deletions
|
@ -9891,6 +9891,7 @@ rb_ibf_load_iseq_complete(rb_iseq_t *iseq)
|
||||||
ibf_load_iseq_each(load, iseq, offset);
|
ibf_load_iseq_each(load, iseq, offset);
|
||||||
ISEQ_COMPILE_DATA_CLEAR(iseq);
|
ISEQ_COMPILE_DATA_CLEAR(iseq);
|
||||||
FL_UNSET(iseq, ISEQ_NOT_LOADED_YET);
|
FL_UNSET(iseq, ISEQ_NOT_LOADED_YET);
|
||||||
|
rb_iseq_init_trace(iseq);
|
||||||
load->iseq = prev_src_iseq;
|
load->iseq = prev_src_iseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10039,8 +10040,6 @@ rb_iseq_ibf_load(VALUE str)
|
||||||
ibf_load_setup(load, loader_obj, str);
|
ibf_load_setup(load, loader_obj, str);
|
||||||
iseq = ibf_load_iseq(load, 0);
|
iseq = ibf_load_iseq(load, 0);
|
||||||
|
|
||||||
rb_iseq_init_trace(iseq);
|
|
||||||
|
|
||||||
RB_GC_GUARD(loader_obj);
|
RB_GC_GUARD(loader_obj);
|
||||||
return iseq;
|
return iseq;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,8 +286,12 @@ class TestISeq < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def strip_lineno(source)
|
||||||
|
source.gsub(/^.*?: /, "")
|
||||||
|
end
|
||||||
|
|
||||||
def sample_iseq
|
def sample_iseq
|
||||||
ISeq.compile <<-EOS.gsub(/^.*?: /, "")
|
ISeq.compile(strip_lineno(<<-EOS))
|
||||||
1: class C
|
1: class C
|
||||||
2: def foo
|
2: def foo
|
||||||
3: begin
|
3: begin
|
||||||
|
@ -439,17 +443,74 @@ class TestISeq < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_binary_tracepoint
|
def collect_from_binary_tracepoint_lines(tracepoint_type, filename)
|
||||||
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
iseq = RubyVM::InstructionSequence.compile(strip_lineno(<<-RUBY), filename)
|
||||||
iseq = RubyVM::InstructionSequence.compile("x = 1\n y = 2", filename)
|
class A
|
||||||
|
class B
|
||||||
|
2.times {
|
||||||
|
def self.foo
|
||||||
|
a = 'good day'
|
||||||
|
raise
|
||||||
|
rescue
|
||||||
|
'dear reader'
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
B.foo
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
iseq_bin = iseq.to_binary
|
iseq_bin = iseq.to_binary
|
||||||
ary = []
|
lines = []
|
||||||
TracePoint.new(:line){|tp|
|
TracePoint.new(tracepoint_type){|tp|
|
||||||
next unless tp.path == filename
|
next unless tp.path == filename
|
||||||
ary << [tp.path, tp.lineno]
|
lines << tp.lineno
|
||||||
}.enable{
|
}.enable{
|
||||||
ISeq.load_from_binary(iseq_bin).eval
|
ISeq.load_from_binary(iseq_bin).eval
|
||||||
}
|
}
|
||||||
assert_equal [[filename, 1], [filename, 2]], ary, '[Bug #14702]'
|
|
||||||
|
lines
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_line_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:line, filename)
|
||||||
|
|
||||||
|
assert_equal [1, 2, 3, 4, 4, 12, 5, 6, 8], lines, '[Bug #14702]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_class_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:class, filename)
|
||||||
|
|
||||||
|
assert_equal [1, 2], lines, '[Bug #14702]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_end_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:end, filename)
|
||||||
|
|
||||||
|
assert_equal [11, 13], lines, '[Bug #14702]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_return_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:return, filename)
|
||||||
|
|
||||||
|
assert_equal [9], lines, '[Bug #14702]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_b_call_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:b_call, filename)
|
||||||
|
|
||||||
|
assert_equal [3, 3], lines, '[Bug #14702]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_binary_b_return_tracepoint
|
||||||
|
filename = "#{File.basename(__FILE__)}_#{__LINE__}"
|
||||||
|
lines = collect_from_binary_tracepoint_lines(:b_return, filename)
|
||||||
|
|
||||||
|
assert_equal [10, 10], lines, '[Bug #14702]'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue