зеркало из https://github.com/github/ruby.git
Fix assertion error when TracePoint has incompatible events
TracePoints with incompatible events (i.e. events not in ISEQ_TRACE_EVENTS) with a method target will fail an assertion error because it does not filter for the supported events. For example, the following lines will cause an assertion error: def foo; end # No arguments passed into TracePoint.new enables all ISEQ_TRACE_EVENTS TracePoint.new {}.enable(target: method(:foo)) # Raise is not supported with a target TracePoint.new(:raise, :return) {}.enable(target: method(:foo)) foo Crashes with: Assertion Failed: vm_insnhelper.c:7026:vm_trace:(iseq_local_events & ~(0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010| 0x0020| 0x0040 | 0x0100 | 0x0200 | 0x4000 | 0x010000| 0x020000)) == 0
This commit is contained in:
Родитель
77ac853c15
Коммит
2fe6a4f84d
|
@ -2307,7 +2307,7 @@ CODE
|
|||
_c = a + b
|
||||
end
|
||||
|
||||
def check_with_events *trace_events
|
||||
def check_with_events(trace_point_events, expected_events = trace_point_events)
|
||||
all_events = [[:call, :method_for_enable_target1],
|
||||
[:line, :method_for_enable_target1],
|
||||
[:line, :method_for_enable_target1],
|
||||
|
@ -2329,7 +2329,7 @@ CODE
|
|||
[:return, :method_for_enable_target1],
|
||||
]
|
||||
events = []
|
||||
TracePoint.new(*trace_events) do |tp|
|
||||
TracePoint.new(*trace_point_events) do |tp|
|
||||
next unless target_thread?
|
||||
events << [tp.event, tp.method_id]
|
||||
end.enable(target: method(:method_for_enable_target1)) do
|
||||
|
@ -2337,15 +2337,23 @@ CODE
|
|||
method_for_enable_target2
|
||||
method_for_enable_target1
|
||||
end
|
||||
assert_equal all_events.find_all{|(ev)| trace_events.include? ev}, events
|
||||
|
||||
exp_events = all_events
|
||||
assert_equal all_events.keep_if { |(ev)| expected_events.include? ev }, events
|
||||
end
|
||||
|
||||
def test_tracepoint_enable_target
|
||||
check_with_events :line
|
||||
check_with_events :call, :return
|
||||
check_with_events :line, :call, :return
|
||||
check_with_events :call, :return, :b_call, :b_return
|
||||
check_with_events :line, :call, :return, :b_call, :b_return
|
||||
check_with_events([:line])
|
||||
check_with_events([:call, :return])
|
||||
check_with_events([:line, :call, :return])
|
||||
check_with_events([:call, :return, :b_call, :b_return])
|
||||
check_with_events([:line, :call, :return, :b_call, :b_return])
|
||||
|
||||
# No arguments passed into TracePoint.new enables all ISEQ_TRACE_EVENTS
|
||||
check_with_events([], [:line, :class, :end, :call, :return, :c_call, :c_return, :b_call, :b_return, :rescue])
|
||||
|
||||
# Raise event should be ignored
|
||||
check_with_events([:line, :raise])
|
||||
end
|
||||
|
||||
def test_tracepoint_nested_enabled_with_target
|
||||
|
|
|
@ -1342,7 +1342,7 @@ void
|
|||
rb_hook_list_connect_tracepoint(VALUE target, rb_hook_list_t *list, VALUE tpval, unsigned int target_line)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
rb_event_hook_t *hook = alloc_event_hook((rb_event_hook_func_t)tp_call_trace, tp->events, tpval,
|
||||
rb_event_hook_t *hook = alloc_event_hook((rb_event_hook_func_t)tp_call_trace, tp->events & ISEQ_TRACE_EVENTS, tpval,
|
||||
RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG);
|
||||
hook->filter.target_line = target_line;
|
||||
hook_list_connect(target, list, hook, FALSE);
|
||||
|
|
Загрузка…
Ссылка в новой задаче