Skip to content

Commit 177deba

Browse files
committed
Always run atexit on the top-level call frame
In the following example, the fiber context and call stack may be in an incomplete state. - In case another thread running mruby is terminated abnormally - In case of a global jump that is out of management by mruby
1 parent 20cf58d commit 177deba

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

src/error.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,17 @@ void
587587
mrb_protect_atexit(mrb_state *mrb)
588588
{
589589
if (mrb->atexit_stack_len > 0) {
590+
if (mrb->c && mrb->c->ci) {
591+
// Even if the call stack is incomplete due to some fault, atexit to be executed at the top level is desirable.
592+
// Clean-up also makes it easier to collect unnecessary objects.
593+
mrb_callinfo zero = { 0 };
594+
struct mrb_context *c = mrb->c = mrb->root_c;
595+
c->ci = c->cibase;
596+
*c->ci = zero;
597+
c->ci->stack = c->stbase;
598+
mrb_gc_arena_restore(mrb, 0);
599+
}
600+
590601
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
591602
struct mrb_jmpbuf c_jmp;
592603
int i = mrb->atexit_stack_len;

0 commit comments

Comments
 (0)