From d72b5d5fbc842ec8d13179d3d400e1fb0cf72f04 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 16 Oct 2025 10:49:25 +0900 Subject: [PATCH] mruby-task: raise exception when task.pass is called from C function when task.pass is called from within a C function (such as Module.new's block evaluation), attempting to yield would cause a segfault because C functions lack valid bytecode program counters (see #6642). this commit adds C function boundary detection to task.pass, raising a runtime error when cci > 0 (indicating execution is inside a C function). this matches fiber's behavior and provides a clear error message instead of a cryptic segfault. unlike the previous commit which allowed sleep to fall back to blocking sleep, task.pass raises an exception because its sole purpose is cooperative yielding - there is no sensible blocking fallback behavior. Co-authored-by: Claude --- mrbgems/mruby-task/src/task.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mrbgems/mruby-task/src/task.c b/mrbgems/mruby-task/src/task.c index bfc789394..0943bd506 100644 --- a/mrbgems/mruby-task/src/task.c +++ b/mrbgems/mruby-task/src/task.c @@ -770,6 +770,14 @@ mrb_task_s_pass(mrb_state *mrb, mrb_value self) task_run_one_iteration(mrb); } else { + /* Check for C function boundary - cannot yield from C function */ + mrb_callinfo *ci; + for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) { + if (ci->cci > 0) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't pass across C function boundary"); + } + } + /* In task context - trigger context switch */ switching_ = TRUE; }