Skip to content

Commit

Permalink
Fix crash in TracePoint c_call for removed method
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
peterzhu2118 committed Jan 4, 2023
1 parent f7243d1 commit 837ef89
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
23 changes: 23 additions & 0 deletions test/ruby/test_settracefunc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@ def test_c_call_no_binding
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__}"
Expand Down
2 changes: 1 addition & 1 deletion vm_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 837ef89

Please sign in to comment.