Support tracing of struct member accessor methods

This follows the same approach used for attr_reader/attr_writer in
2d98593bf5, skipping the checking for
tracing after the first call using the call cache, and clearing the
call cache when tracing is turned on/off.

Fixes [Bug #18886]
This commit is contained in:
Jeremy Evans 2023-10-26 17:03:17 -07:00
parent 1721bb9dc6
commit 3081c83169
5 changed files with 118 additions and 22 deletions

View file

@ -955,6 +955,55 @@ CODE
assert_equal(expected*2, events)
end
def test_tracepoint_struct
c = Struct.new(:x) do
alias y x
alias y= x=
end
obj = c.new
ar_meth = obj.method(:x)
aw_meth = obj.method(:x=)
aar_meth = obj.method(:y)
aaw_meth = obj.method(:y=)
events = []
trace = TracePoint.new(:c_call, :c_return){|tp|
next if !target_thread?
next if tp.path != __FILE__
next if tp.method_id == :call
case tp.event
when :c_call
assert_raise(RuntimeError) {tp.return_value}
events << [tp.event, tp.method_id, tp.callee_id]
when :c_return
events << [tp.event, tp.method_id, tp.callee_id, tp.return_value]
end
}
test_proc = proc do
obj.x = 1
obj.x
obj.y = 2
obj.y
aw_meth.call(1)
ar_meth.call
aaw_meth.call(2)
aar_meth.call
end
test_proc.call # populate call caches
trace.enable(&test_proc)
expected = [
[:c_call, :x=, :x=],
[:c_return, :x=, :x=, 1],
[:c_call, :x, :x],
[:c_return, :x, :x, 1],
[:c_call, :x=, :y=],
[:c_return, :x=, :y=, 2],
[:c_call, :x, :y],
[:c_return, :x, :y, 2],
]
assert_equal(expected*2, events)
end
class XYZZYException < Exception; end
def method_test_tracepoint_raised_exception err
raise err