Skip to content

Commit cfa578d

Browse files
authored
Merge pull request #1190 from Unity-Technologies/unity-master-debugger-async-crash
Fix crash during async debugging (case 1153078). Apply partial patch …
2 parents f2dfa4c + 98e0344 commit cfa578d

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

mono/mini/debugger-agent.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,7 +5345,10 @@ get_set_notification_method (MonoClass* async_builder_class)
53455345
MonoError error;
53465346
GPtrArray* array = mono_class_get_methods_by_name (async_builder_class, "SetNotificationForWaitCompletion", 0x24, FALSE, FALSE, &error);
53475347
mono_error_assert_ok (&error);
5348-
g_assert (array->len == 1);
5348+
if (array->len == 0) {
5349+
g_ptr_array_free (array, TRUE);
5350+
return NULL;
5351+
}
53495352
MonoMethod* set_notification_method = (MonoMethod *)g_ptr_array_index (array, 0);
53505353
g_ptr_array_free (array, TRUE);
53515354
return set_notification_method;
@@ -5431,7 +5434,9 @@ get_this_async_id (StackFrame *frame)
54315434
return get_objid (obj);
54325435
}
54335436

5434-
static void
5437+
// Returns true if TaskBuilder has NotifyDebuggerOfWaitCompletion method
5438+
// false if not(AsyncVoidBuilder)
5439+
static gboolean
54355440
set_set_notification_for_wait_completion_flag (StackFrame *frame)
54365441
{
54375442
MonoClassField *builder_field = mono_class_get_field_from_name (frame->method->klass, "<>t__builder");
@@ -5443,11 +5448,15 @@ set_set_notification_for_wait_completion_flag (StackFrame *frame)
54435448
gboolean arg = TRUE;
54445449
MonoError error;
54455450
args [0] = &arg;
5446-
mono_runtime_invoke_checked (get_set_notification_method (mono_class_from_mono_type (mono_field_get_type (builder_field))), builder, args, &error);
5451+
MonoMethod *method = get_set_notification_method (mono_class_from_mono_type (mono_field_get_type (builder_field)));
5452+
if (method == NULL)
5453+
return FALSE;
5454+
mono_runtime_invoke_checked (method, builder, args, &error);
54475455
mono_error_assert_ok (&error);
5456+
return TRUE;
54485457
}
54495458

5450-
static MonoMethod* notify_debugger_of_wait_completion_method_cache = NULL;
5459+
static MonoMethod* notify_debugger_of_wait_completion_method_cache;
54515460

54525461
static MonoMethod*
54535462
get_notify_debugger_of_wait_completion_method (void)
@@ -6438,14 +6447,16 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI
64386447
ss_req->depth = STEP_DEPTH_OUT;//setting depth to step-out is important, don't inline IF, because code later depends on this
64396448
}
64406449
if (ss_req->depth == STEP_DEPTH_OUT) {
6441-
set_set_notification_for_wait_completion_flag (frames [0]);
6442-
ss_req->async_id = get_this_async_id (frames [0]);
6443-
ss_req->async_stepout_method = get_notify_debugger_of_wait_completion_method ();
6444-
ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, ss_req->async_stepout_method, 0);
6445-
if (ss_req_bp_cache)
6446-
g_hash_table_destroy (ss_req_bp_cache);
6447-
mono_debug_free_method_async_debug_info (asyncMethod);
6448-
return;
6450+
//If we are inside `async void` method, do normal step-out
6451+
if (set_set_notification_for_wait_completion_flag (frames [0])) {
6452+
ss_req->async_id = get_this_async_id (frames [0]);
6453+
ss_req->async_stepout_method = get_notify_debugger_of_wait_completion_method ();
6454+
ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, ss_req->async_stepout_method, 0);
6455+
if (ss_req_bp_cache)
6456+
g_hash_table_destroy (ss_req_bp_cache);
6457+
mono_debug_free_method_async_debug_info (asyncMethod);
6458+
return;
6459+
}
64496460
}
64506461
}
64516462

0 commit comments

Comments
 (0)