Bug #17650
closedTracePoint doesn't receive :fiber_switch events when raising exceptions
Description
It seems to me the :fiber_switch
event should be raised for every fiber switch, unless there's some very important reason not to, e.g. maybe it makes sense to skip the event when a fiber terminates with a fatal error. In addition to sending the event, there's some other fiber cleanup code in fiber_switch
that is skipped after raising an exception: checking thread interrupts and incrementing th->blocking
. Maybe this is intended behavior? But it all seems like a bug to me.
I've captured the expected behavior in this test (which fails on master
):
evs = []
f = nil
TracePoint.new(:raise, :fiber_switch){|tp|
next unless target_thread?
evs << [tp.event, Fiber.current]
}.enable{
f = Fiber.new{
Fiber.yield # will raise
Fiber.yield # unreachable
}
begin
f.resume
f.raise StopIteration
rescue StopIteration
evs << :rescued
end
}
assert_equal [:fiber_switch, f], evs[0], "initial resume"
assert_equal [:fiber_switch, Fiber.current], evs[1], "Fiber.yield"
# fiber switch event comes before the exception is raised:
assert_equal [:fiber_switch, f], evs[2], "fiber.raise"
assert_equal [:raise, f], evs[3], "fiber.raise"
# fiber switch event comes before the exception is raised:
assert_equal [:fiber_switch, Fiber.current], evs[4], "terminated with raise"
assert_equal [:raise, Fiber.current], evs[5], "terminated with raise"
assert_equal :rescued, evs[6]
assert_equal 7, evs.size
I've attempted to fix this in a PR here: https://github.com/ruby/ruby/pull/4207
That PR moves the rb_exc_raise
after all of the other fiber_switch
cleanup code. It also changes fiber termination with an unhandled exception to pass the exception to its return_fiber
in the same way as Fiber#raise
(via fiber->cont.value
and fiber->cont.argc == -1
) instead of via a thread interrupt, which can lead to unexpected and difficult to debug behavior. Fatal errors are still passed via rb_threadptr_pending_interrupt_enque
.
Updated by jeremyevans0 (Jeremy Evans) about 3 years ago
- Status changed from Open to Closed
PR merged at 3ee4fa9491d0b2b5fb40deea8e93e797924de789.