Fix fallback when abnormal error happens

It is not likely happens but if happened, in pattern 1, the whole
process abort when mrb->jmp is NULL.
Instead, make the status MRB_TASK_STOPPED and delegate following
logic of "Handle task termination"
This commit is contained in:
HASUMI Hitoshi
2026-05-29 01:30:24 +09:00
parent f1232334c0
commit a502be4f9f
+12 -9
View File
@@ -389,6 +389,18 @@ execute_task(mrb_state *mrb, mrb_task *t)
prev_c->ci = prev_ci;
prev_ci->cci = prev_cci;
/* If an abnormal path inside mrb_vm_exec() bypassed
exception_as_result and unwound via MRB_THROW (e.g. a
CINFO_SKIP frame), mrb_protect_error caught it and stored the
exception object in t->result. Force the task to terminate
cleanly so the scheduler keeps running instead of aborting -
re-raising into the scheduler would abort in pattern 1, where
no outer jmpbuf exists. The exception remains observable via
mrb_task_value() / Task#value. */
if (error) {
t->c.status = MRB_TASK_STOPPED;
}
/* Handle task termination */
if (t->c.status == MRB_TASK_STOPPED) {
switching_ = FALSE;
@@ -405,15 +417,6 @@ execute_task(mrb_state *mrb, mrb_task *t)
/* Task yielded but still running - move to ready queue */
t->status = MRB_TASK_STATUS_READY;
}
/* Fallback for abnormal cases that bypass exception_as_result:
e.g. a CINFO_SKIP frame or some other path inside mrb_vm_exec()
unwound via MRB_THROW instead of returning the exception as a
value. Normal unhandled task exceptions never reach this branch;
they are captured into t->result by execute_task_vm() above. */
if (error) {
mrb_exc_raise(mrb, t->result);
}
}
/* Tick handler - called by timer interrupt */