diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2016-03-06 12:15:55 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2016-03-06 12:15:55 +0900 |
| commit | b4d946f6bccffa4cd6b1a89b13cf0a6f76d8f3ff (patch) | |
| tree | 18da5408ccc2a372b859162a386caf754ac36795 | |
| parent | 1a4540fb4aa53ee438b5fa65e28f3ad39537c39e (diff) | |
| parent | f1eb3aea114cbd1e2622cbe9618571f3e1eec115 (diff) | |
| download | mruby-b4d946f6bccffa4cd6b1a89b13cf0a6f76d8f3ff.tar.gz mruby-b4d946f6bccffa4cd6b1a89b13cf0a6f76d8f3ff.zip | |
Merge pull request #3129 from kou/fix-segv-by-backtrace-and-gc
Fix SEGV by backtrace and GC
| -rw-r--r-- | src/backtrace.c | 9 | ||||
| -rw-r--r-- | src/error.c | 9 | ||||
| -rw-r--r-- | src/gc.c | 5 |
3 files changed, 14 insertions, 9 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index 5bf6d3196..45a8cc2de 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 14e4ab4d3..13032b136 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; @@ -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: |
