Reset monitoring reraise suppression at exception lifecycle boundaries

Clear the existing thread-local suppression flag when a handler receives an exception or an exception escapes a frame, independently of optional monitoring event masks.

Assisted-by: OpenAI Codex:model identifier unavailable
This commit is contained in:
dot committed 2026-10-13 11:06:28 +09:00
1 parent ec206b1125
commit 191fe58873
2 files changed
+11 -2

No files matched your search

+3
View File
@@ -4171,6 +4171,7 @@ impl ExecutingFrame<'_> {
Ok(None) => next_idx = lasti_cell.load(Relaxed), Ok(None) => next_idx = lasti_cell.load(Relaxed),
Ok(Some(result)) => break Ok(Some(result)), Ok(Some(result)) => break Ok(Some(result)),
Err(exception) => { Err(exception) => {
monitoring::reset_reraise_pending();
// Fire PY_UNWIND: exception escapes this frame // Fire PY_UNWIND: exception escapes this frame
let exception = if vm.state.monitoring_events.load() let exception = if vm.state.monitoring_events.load()
& MonitoringEvent::PyUnwind.mask() & MonitoringEvent::PyUnwind.mask()
@@ -4454,6 +4455,7 @@ impl ExecutingFrame<'_> {
} }
Ok(Some(result)) => Ok(result), Ok(Some(result)) => Ok(result),
Err(exception) => { Err(exception) => {
monitoring::reset_reraise_pending();
// Fire PY_UNWIND: exception escapes the generator frame. // Fire PY_UNWIND: exception escapes the generator frame.
let exception = let exception =
if vm.state.monitoring_events.load() & MonitoringEvent::PyUnwind.mask() != 0 { if vm.state.monitoring_events.load() & MonitoringEvent::PyUnwind.mask() != 0 {
@@ -8922,6 +8924,7 @@ impl ExecutingFrame<'_> {
if let Some(entry) = if let Some(entry) =
bytecode::find_exception_handler(&self.code.exceptiontable, offset) bytecode::find_exception_handler(&self.code.exceptiontable, offset)
{ {
monitoring::reset_reraise_pending();
// Fire EXCEPTION_HANDLED before setting up handler. // Fire EXCEPTION_HANDLED before setting up handler.
// If the callback raises, the handler is NOT set up and the // If the callback raises, the handler is NOT set up and the
// new exception propagates instead. // new exception propagates instead.
+8 -2
View File
@@ -1083,6 +1083,12 @@ pub(crate) fn fire_raise(
) )
} }
/// End suppression when the exception reaches a handler or escapes a frame,
/// independently of whether either lifecycle event has a registered callback.
pub(crate) fn reset_reraise_pending() {
RERAISE_PENDING.with(|f| f.set(false));
}
/// Only fires if no RERAISE has been fired since the last EXCEPTION_HANDLED, /// Only fires if no RERAISE has been fired since the last EXCEPTION_HANDLED,
/// preventing duplicate events from chained cleanup handlers. /// preventing duplicate events from chained cleanup handlers.
pub(crate) fn fire_reraise( pub(crate) fn fire_reraise(
@@ -1114,7 +1120,7 @@ pub(crate) fn fire_exception_handled(
offset: u32, offset: u32,
exception: &PyObject, exception: &PyObject,
) -> PyResult<()> { ) -> PyResult<()> {
RERAISE_PENDING.with(|f| f.set(false)); reset_reraise_pending();
fire( fire(
vm, vm,
MonitoringEvent::ExceptionHandled, MonitoringEvent::ExceptionHandled,
@@ -1130,7 +1136,7 @@ pub(crate) fn fire_py_unwind(
offset: u32, offset: u32,
exception: &PyObject, exception: &PyObject,
) -> PyResult<()> { ) -> PyResult<()> {
RERAISE_PENDING.with(|f| f.set(false)); reset_reraise_pending();
fire( fire(
vm, vm,
MonitoringEvent::PyUnwind, MonitoringEvent::PyUnwind,