+ MonoDebugMethodAsyncInfo* asyncMethod = mono_debug_lookup_method_async_debug_info (method);
+
+ /* Need to stop in catch clauses as well */
+ for (i = ss_req->depth == STEP_DEPTH_OUT ? 1 : 0; i < nframes; ++i) {
+ StackFrame *frame = frames [i];
+
+ if (frame->ji) {
+ MonoJitInfo *jinfo = frame->ji;
+ for (j = 0; j < jinfo->num_clauses; ++j) {
+ // In case of async method we don't want to place breakpoint on last catch handler(which state machine added for whole method)
+ if (asyncMethod && asyncMethod->num_awaits && i == 0 && j + 1 == jinfo->num_clauses)
+ break;
+ MonoJitExceptionInfo *ei = &jinfo->clauses [j];
+
+ if (mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp))
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, local_sp.il_offset);
+ }
+ }
+ }
+
+ if (asyncMethod && asyncMethod->num_awaits && nframes && ensure_jit (frames [0])) {
+ //asyncMethod has value and num_awaits > 0, this means we are inside async method with awaits
+
+ // Check if we hit yield_offset during normal stepping, because if we did...
+ // Go into special async stepping mode which places breakpoint on resumeOffset
+ // of this await call and sets async_id so we can distinguish it from parallel executions
+ for (i = 0; i < asyncMethod->num_awaits; i++) {
+ if (sp->il_offset == asyncMethod->yield_offsets [i]) {
+ ss_req->async_id = get_this_async_id (frames [0]);
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, method, asyncMethod->resume_offsets [i]);
+ if (ss_req_bp_cache)
+ g_hash_table_destroy (ss_req_bp_cache);
+ mono_debug_free_method_async_debug_info (asyncMethod);
+ return;
+ }
+ }
+ //If we are at end of async method and doing step-in or step-over...
+ //Switch to step-out, so whole NotifyDebuggerOfWaitCompletion magic happens...
+ if (is_last_non_empty (sp, info)) {
+ ss_req->depth = STEP_DEPTH_OUT;//setting depth to step-out is important, don't inline IF, because code later depends on this
+ }
+ if (ss_req->depth == STEP_DEPTH_OUT) {
+ set_set_notification_for_wait_completion_flag (frames [0]);
+ ss_req->async_id = get_this_async_id (frames [0]);
+ ss_req->async_stepout_method = get_notify_debugger_of_wait_completion_method ();
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, ss_req->async_stepout_method, 0);
+ if (ss_req_bp_cache)
+ g_hash_table_destroy (ss_req_bp_cache);
+ mono_debug_free_method_async_debug_info (asyncMethod);
+ return;
+ }
+ }
+
+ if (asyncMethod)
+ mono_debug_free_method_async_debug_info (asyncMethod);
+