+static MonoObject*
+get_this (StackFrame *frame)
+{
+ //Logic inspiered by "add_var" method and took out path that happens in async method for getting this
+ MonoDebugVarInfo *var = frame->jit->this_var;
+ if ((var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS) != MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET)
+ return NULL;
+
+ guint8 * addr = (guint8 *)mono_arch_context_get_int_reg (&frame->ctx, var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS);
+ addr += (gint32)var->offset;
+ return *(MonoObject**)addr;
+}
+
+//This ID is used to figure out if breakpoint hit on resumeOffset belongs to us or not
+//since thread probably changed...
+static int
+get_this_async_id (StackFrame *frame)
+{
+ return get_objid (get_this (frame));
+}
+
+static MonoMethod* set_notification_method_cache = NULL;
+
+static MonoMethod*
+get_set_notification_method ()
+{
+ if(set_notification_method_cache != NULL)
+ return set_notification_method_cache;
+ MonoError error;
+ MonoClass* async_builder_class = mono_class_load_from_name (mono_defaults.corlib, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
+ GPtrArray* array = mono_class_get_methods_by_name (async_builder_class, "SetNotificationForWaitCompletion", 0x24, FALSE, FALSE, &error);
+ mono_error_assert_ok (&error);
+ g_assert (array->len == 1);
+ set_notification_method_cache = (MonoMethod *)g_ptr_array_index (array, 0);
+ g_ptr_array_free (array, TRUE);
+ return set_notification_method_cache;
+}
+
+static void
+set_set_notification_for_wait_completion_flag (StackFrame *frame)
+{
+ MonoObject* obj = get_this (frame);
+ g_assert (obj);
+ MonoClassField *builder_field = mono_class_get_field_from_name (obj->vtable->klass, "<>t__builder");
+ g_assert (builder_field);
+ MonoObject* builder;
+ MonoError error;
+ builder = mono_field_get_value_object_checked (frame->domain, builder_field, obj, &error);
+ mono_error_assert_ok (&error);
+ g_assert (builder);
+
+ void* args [1];
+ gboolean arg = TRUE;
+ args [0] = &arg;
+ mono_runtime_invoke_checked (get_set_notification_method(), mono_object_unbox (builder), args, &error);
+ mono_error_assert_ok (&error);
+ mono_field_set_value (obj, builder_field, mono_object_unbox (builder));
+}
+
+static MonoMethod* notify_debugger_of_wait_completion_method_cache = NULL;
+
+static MonoMethod*
+get_notify_debugger_of_wait_completion_method ()
+{
+ if (notify_debugger_of_wait_completion_method_cache != NULL)
+ return notify_debugger_of_wait_completion_method_cache;
+ MonoError error;
+ MonoClass* task_class = mono_class_load_from_name (mono_defaults.corlib, "System.Threading.Tasks", "Task");
+ GPtrArray* array = mono_class_get_methods_by_name (task_class, "NotifyDebuggerOfWaitCompletion", 0x24, FALSE, FALSE, &error);
+ mono_error_assert_ok (&error);
+ g_assert (array->len == 1);
+ notify_debugger_of_wait_completion_method_cache = (MonoMethod *)g_ptr_array_index (array, 0);
+ g_ptr_array_free (array, TRUE);
+ return notify_debugger_of_wait_completion_method_cache;
+}
+