diff --git a/vm.c b/vm.c
index 3c1e8b4..63514f5 100644
--- a/vm.c
+++ b/vm.c
@@ -415,6 +415,23 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp,
     if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
 	/* TODO */
 	env->block.iseq = 0;
+    } else {
+	/* rewrite dfp in errinfo to point to heap */
+	if (cfp->iseq->type == ISEQ_TYPE_RESCUE ||
+	    cfp->iseq->type == ISEQ_TYPE_ENSURE) {
+	    VALUE errinfo = env->env[0]; /* #$! */
+	    if (RB_TYPE_P(errinfo, T_NODE)) {
+		VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
+		if (! ENV_IN_HEAP_P(th, escape_dfp)) {
+		    VALUE dfpval = *escape_dfp;
+		    if (CLASS_OF(dfpval) == rb_cEnv) {
+			rb_env_t *dfpenv;
+			GetEnvPtr(dfpval, dfpenv);
+			SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
+		    }
+		}
+	    }
+	}
     }
     return envval;
 }
