Fix crash in TracePoint c_call for removed method

trace_arg->id is the ID of the original method of an aliased method. If
the original method is removed, then the lookup will fail. We should use
trace_arg->called_id instead, which is the ID of the aliased method.

Fixes [Bug #19305]
This commit is contained in:
Peter Zhu 2023-01-04 13:15:59 -05:00
Родитель f7243d1afb
Коммит 837ef8911c
2 изменённых файлов: 24 добавлений и 1 удалений

Просмотреть файл

@ -70,6 +70,29 @@ class TestSetTraceFunc < Test::Unit::TestCase
assert_nil(binding)
end
def test_c_call_removed_method
# [Bug #19305]
klass = Class.new do
attr_writer :bar
alias_method :set_bar, :bar=
remove_method :bar=
end
obj = klass.new
method_id = nil
parameters = nil
TracePoint.new(:c_call) { |tp|
method_id = tp.method_id
parameters = tp.parameters
}.enable {
obj.set_bar(1)
}
assert_equal(:bar=, method_id)
assert_equal([[:req]], parameters)
end
def test_call
events = []
name = "#{self.class}\##{__method__}"

Просмотреть файл

@ -915,7 +915,7 @@ rb_tracearg_parameters(rb_trace_arg_t *trace_arg)
if (trace_arg->klass && trace_arg->id) {
const rb_method_entry_t *me;
VALUE iclass = Qnil;
me = rb_method_entry_without_refinements(trace_arg->klass, trace_arg->id, &iclass);
me = rb_method_entry_without_refinements(trace_arg->klass, trace_arg->called_id, &iclass);
return rb_unnamed_parameters(rb_method_entry_arity(me));
}
break;