Skip to content

Commit 842b6a8

Browse files
authored
[mono][interp] Fix invocation of finally clauses with tiering enabled (#69909)
When unwinding the stack during EH, we first populate a StackFrameInfo with various data, like native_offset and jinfo. Let's assume this data is for an untiered method. If this frame has multiple finally clauses that need to be invoked, a finally invocation could tier up the InterpFrame that it is executing. The future finally invocations would use the IPs from the previously resolved untiered method. This change makes the interpreter receive only the clause index (in interp_run_finally) so we correctly resolve the native offsets of the handler.
1 parent c0227b4 commit 842b6a8

File tree

4 files changed

+7
-6
lines changed

4 files changed

+7
-6
lines changed

src/mono/mono/mini/ee.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef gpointer MonoInterpFrameHandle;
3636
MONO_EE_CALLBACK (void, delegate_ctor, (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoError *error)) \
3737
MONO_EE_CALLBACK (void, set_resume_state, (MonoJitTlsData *jit_tls, MonoObject *ex, MonoJitExceptionInfo *ei, MonoInterpFrameHandle interp_frame, gpointer handler_ip)) \
3838
MONO_EE_CALLBACK (void, get_resume_state, (const MonoJitTlsData *jit_tls, gboolean *has_resume_state, MonoInterpFrameHandle *interp_frame, gpointer *handler_ip)) \
39-
MONO_EE_CALLBACK (gboolean, run_finally, (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \
39+
MONO_EE_CALLBACK (gboolean, run_finally, (StackFrameInfo *frame, int clause_index)) \
4040
MONO_EE_CALLBACK (gboolean, run_filter, (StackFrameInfo *frame, MonoException *ex, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \
4141
MONO_EE_CALLBACK (gboolean, run_clause_with_il_state, (gpointer il_state, int clause_index, MonoObject *ex, gboolean *filtered)) \
4242
MONO_EE_CALLBACK (void, frame_iter_init, (MonoInterpStackIter *iter, gpointer interp_exit_data)) \

src/mono/mono/mini/interp-stubs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ stub_get_resume_state (const MonoJitTlsData *jit_tls, gboolean *has_resume_state
102102
}
103103

104104
static gboolean
105-
stub_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end)
105+
stub_run_finally (StackFrameInfo *frame, int clause_index)
106106
{
107107
g_assert_not_reached ();
108108
}

src/mono/mono/mini/interp/interp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7390,16 +7390,17 @@ interp_get_resume_state (const MonoJitTlsData *jit_tls, gboolean *has_resume_sta
73907390
* Return TRUE if the finally clause threw an exception.
73917391
*/
73927392
static gboolean
7393-
interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end)
7393+
interp_run_finally (StackFrameInfo *frame, int clause_index)
73947394
{
73957395
InterpFrame *iframe = (InterpFrame*)frame->interp_frame;
7396+
MonoJitExceptionInfo *ei = &iframe->imethod->jinfo->clauses [clause_index];
73967397
ThreadContext *context = get_context ();
73977398
FrameClauseArgs clause_args;
73987399
const guint16 *state_ip;
73997400

74007401
memset (&clause_args, 0, sizeof (FrameClauseArgs));
7401-
clause_args.start_with_ip = (const guint16*)handler_ip;
7402-
clause_args.end_at_ip = (const guint16*)handler_ip_end;
7402+
clause_args.start_with_ip = (const guint16*)ei->handler_start;
7403+
clause_args.end_at_ip = (const guint16*)ei->data.handler_end;
74037404
clause_args.exec_frame = iframe;
74047405

74057406
state_ip = iframe->state.ip;

src/mono/mono/mini/mini-exceptions.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2576,7 +2576,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
25762576
g_print ("EXCEPTION: finally/fault clause found in AOTed code, running it with the interpreter.\n");
25772577
mini_get_interp_callbacks ()->run_clause_with_il_state (frame.il_state, i, NULL, NULL);
25782578
} else if (in_interp) {
2579-
gboolean has_ex = mini_get_interp_callbacks ()->run_finally (&frame, i, ei->handler_start, ei->data.handler_end);
2579+
gboolean has_ex = mini_get_interp_callbacks ()->run_finally (&frame, i);
25802580
if (has_ex) {
25812581
/*
25822582
* If run_finally didn't resume to a context, it means that the handler frame

0 commit comments

Comments
 (0)