diff options
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index ac2b5ae..e0c59a1 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2773,6 +2773,7 @@ fetch_inferior_event (void *client_data) if (non_stop && ecs->ws.kind != TARGET_WAITKIND_IGNORE + && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED && ecs->ws.kind != TARGET_WAITKIND_EXITED && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) /* In non-stop mode, each thread is handled individually. Switch @@ -2806,6 +2807,7 @@ fetch_inferior_event (void *client_data) normal_stop (); if (target_has_execution + && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED && ecs->ws.kind != TARGET_WAITKIND_EXITED && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->event_thread->step_multi @@ -3164,8 +3166,24 @@ handle_inferior_event (struct execution_control_state *ecs) return; } + if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED + && target_can_async_p () && !sync_execution) + { + /* There were no unwaited-for children left in the target, but, + we're not synchronously waiting for events either. Just + ignore. Otherwise, if we were running a synchronous + execution command, we need to cancel it and give the user + back the terminal. */ + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, + "infrun: TARGET_WAITKIND_NO_RESUMED (ignoring)\n"); + prepare_to_wait (ecs); + return; + } + if (ecs->ws.kind != TARGET_WAITKIND_EXITED - && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) + && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED + && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED) { struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid)); @@ -3182,6 +3200,18 @@ handle_inferior_event (struct execution_control_state *ecs) /* Always clear state belonging to the previous time we stopped. */ stop_stack_dummy = STOP_NONE; + if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED) + { + /* No unwaited-for children left. IOW, all resumed children + have exited. */ + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n"); + + stop_print_frame = 0; + stop_stepping (ecs); + return; + } + /* If it's a new process, add it to the thread database. */ ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid) @@ -5824,7 +5854,8 @@ normal_stop (void) if (!non_stop) make_cleanup (finish_thread_state_cleanup, &minus_one_ptid); else if (last.kind != TARGET_WAITKIND_SIGNALLED - && last.kind != TARGET_WAITKIND_EXITED) + && last.kind != TARGET_WAITKIND_EXITED + && last.kind != TARGET_WAITKIND_NO_RESUMED) make_cleanup (finish_thread_state_cleanup, &inferior_ptid); /* In non-stop mode, we don't want GDB to switch threads behind the @@ -5843,7 +5874,8 @@ normal_stop (void) && !ptid_equal (previous_inferior_ptid, inferior_ptid) && target_has_execution && last.kind != TARGET_WAITKIND_SIGNALLED - && last.kind != TARGET_WAITKIND_EXITED) + && last.kind != TARGET_WAITKIND_EXITED + && last.kind != TARGET_WAITKIND_NO_RESUMED) { target_terminal_ours_for_output (); printf_filtered (_("[Switching to %s]\n"), @@ -5852,6 +5884,14 @@ normal_stop (void) previous_inferior_ptid = inferior_ptid; } + if (last.kind == TARGET_WAITKIND_NO_RESUMED) + { + gdb_assert (sync_execution || !target_can_async_p ()); + + target_terminal_ours_for_output (); + printf_filtered (_("No unwaited-for children left.\n")); + } + if (!breakpoints_always_inserted_mode () && target_has_execution) { if (remove_breakpoints ()) @@ -6038,6 +6078,7 @@ done: if (!target_has_execution || last.kind == TARGET_WAITKIND_SIGNALLED || last.kind == TARGET_WAITKIND_EXITED + || last.kind == TARGET_WAITKIND_NO_RESUMED || (!inferior_thread ()->step_multi && !(inferior_thread ()->control.stop_bpstat && inferior_thread ()->control.proceed_to_finish) |