diff --git a/src/backtrace.c b/src/backtrace.c index 5bf6d31962ea25e97012f0895e2d12fbdfb1d040..45a8cc2dee3842b28acb3389f36b96b0062b036b 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -111,8 +111,6 @@ each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func mrb_callinfo *ci; mrb_irep *irep; mrb_code *pc; - - loc.lineno = -1; ci = &mrb->c->cibase[i]; @@ -130,11 +128,8 @@ each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func else { pc = pc0; } - - if (irep) { - loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq)); - loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq)); - } + loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq)); + loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq)); if (loc.lineno == -1) continue; diff --git a/src/error.c b/src/error.c index 14e4ab4d3a04beb852aad6c95955486d583170d3..13032b1363ce470c7dfd61649180a9de1f916ff7 100644 --- a/src/error.c +++ b/src/error.c @@ -255,17 +255,22 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc) { if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) { mrb_value target_exc = mrb_nil_value(); + int ai; + + ai = mrb_gc_arena_save(mrb); if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) { target_exc = mrb_obj_value(mrb->exc); } - else if (!mrb_nil_p(exc) && mrb_obj_ptr(exc) == mrb->backtrace.exc) { - target_exc = exc; + else if (!mrb_nil_p(exc) && mrb->backtrace.exc) { + target_exc = mrb_obj_value(mrb->backtrace.exc); + mrb_gc_protect(mrb, target_exc); } if (!mrb_nil_p(target_exc)) { mrb_value backtrace; backtrace = mrb_restore_backtrace(mrb); set_backtrace(mrb, target_exc, backtrace); } + mrb_gc_arena_restore(mrb, ai); } mrb->backtrace.n = 0; diff --git a/src/gc.c b/src/gc.c index b23e4869e8779ee2b903d67545b25dd4ce399486..e7948e4f50ef09ff5eb50afcf2ac2bfcbf81b897 100644 --- a/src/gc.c +++ b/src/gc.c @@ -695,8 +695,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj) #endif case MRB_TT_OBJECT: + mrb_gc_free_iv(mrb, (struct RObject*)obj); + break; + case MRB_TT_EXCEPTION: mrb_gc_free_iv(mrb, (struct RObject*)obj); + if ((struct RObject*)obj == mrb->backtrace.exc) + mrb->backtrace.exc = 0; break; case MRB_TT_CLASS: