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: