未验证 提交 7fa37037 编写于 作者: Z Zoltan Varga 提交者: GitHub

[mono] Stop first pass exception handling when exiting the interpreter in llvmonly mode. (#50007)

* [mono] Add a FRAME_TYPE_INTERP_ENTRY frame type to the unwinder, it marks the location where execution transfers
to the interpreter.

* [mono] Stop first pass exception handling when exiting the interpreter in llvmonly mode.

Otherwise, you could end up with the following situation:
- [1] interpreted frame
- [2] AOTed frame catching the exception
- [3] interpreted frame catching the same exception

The EH code would think frame [3] caught the exception, setting up interpreter state for
resuming there, but frame [2] would catch the exception, so the exception state in
the interpreter would not be cleared, leading to an assert in interp_entry ().

Fixes https://github.com/dotnet/runtime/issues/47334.
上级 72e2420f
......@@ -1670,6 +1670,7 @@ stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
case FRAME_TYPE_TRAMPOLINE:
case FRAME_TYPE_INTERP_TO_MANAGED:
case FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX:
case FRAME_TYPE_INTERP_ENTRY:
return FALSE;
case FRAME_TYPE_MANAGED:
case FRAME_TYPE_INTERP:
......
......@@ -762,7 +762,7 @@ unwinder_unwind_frame (Unwinder *unwinder,
}
if (!unwinder->in_interp)
return unwinder_unwind_frame (unwinder, jit_tls, prev_ji, ctx, new_ctx, trace, lmf, save_locations, frame);
frame->type = FRAME_TYPE_INTERP_ENTRY;
return TRUE;
} else {
gboolean res = mono_find_jit_info_ext (jit_tls, prev_ji, ctx, new_ctx, trace, lmf,
......@@ -1874,6 +1874,7 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
case FRAME_TYPE_TRAMPOLINE:
case FRAME_TYPE_INTERP_TO_MANAGED:
case FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX:
case FRAME_TYPE_INTERP_ENTRY:
continue;
case FRAME_TYPE_INTERP:
case FRAME_TYPE_MANAGED:
......@@ -2280,6 +2281,15 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt
case FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX:
*ctx = new_ctx;
continue;
case FRAME_TYPE_INTERP_ENTRY:
if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY_INTERP)
/*
* There might be AOTed frames above the intepreted frames which can handle the exception,
* so stop first pass, the caller will rethrow the exception, starting the process again.
*/
return MONO_FIRST_PASS_UNHANDLED;
*ctx = new_ctx;
continue;
case FRAME_TYPE_INTERP:
case FRAME_TYPE_MANAGED:
break;
......@@ -2734,6 +2744,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
case FRAME_TYPE_MANAGED_TO_NATIVE:
case FRAME_TYPE_TRAMPOLINE:
case FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX:
case FRAME_TYPE_INTERP_ENTRY:
*ctx = new_ctx;
continue;
case FRAME_TYPE_INTERP_TO_MANAGED:
......
......@@ -28,7 +28,9 @@ typedef enum {
FRAME_TYPE_INTERP_TO_MANAGED = 5,
/* same, but with MonoContext */
FRAME_TYPE_INTERP_TO_MANAGED_WITH_CTX = 6,
FRAME_TYPE_NUM = 7
/* Frame for transitioning to interpreted code */
FRAME_TYPE_INTERP_ENTRY = 7,
FRAME_TYPE_NUM = 8
} MonoStackFrameType;
typedef enum {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册