From 0e5bf2a8c930b383586bcf0476859e55571da0c7 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 28 Oct 2011 18:30:00 +0000 Subject: 2011-10-28 Pedro Alves gdb/ * linux-nat.c (linux_nat_filter_event): Remove `options' parameter, and dead code that used it. If we're handling a PTRACE_EVENT_EXEC event, and the thread group leader is no longer in our lwp list, re-add it. (check_zombie_leaders): New. (linux_nat_wait_1): Remove `options' and `pid' locals. Always wait for children with WNOHANG, and always wait for all children. Don't check for no resumed children upfront. Simplify wait loop. Check for zombie thread group leaders after handling all wait statuses. Return TARGET_WAITKIND_NO_RESUMED if there no unwaited-for children left. * infrun.c (fetch_inferior_event): Handle TARGET_WAITKIND_NO_RESUMED. (handle_inferior_event): Handle TARGET_WAITKIND_NO_RESUMED. (normal_stop): Handle TARGET_WAITKIND_NO_RESUMED. * target.h (enum target_waitkind) : New. gdb/testsuite/ * gdb.threads/no-unwaited-for-left.c: New. * gdb.threads/no-unwaited-for-left.exp: New. * gdb.threads/non-ldr-exc-1.c: New. * gdb.threads/non-ldr-exc-1.exp: New. * gdb.threads/non-ldr-exc-2.c: New. * gdb.threads/non-ldr-exc-2.exp: New. * gdb.threads/non-ldr-exc-3.c: New. * gdb.threads/non-ldr-exc-3.exp: New. * gdb.threads/non-ldr-exc-4.c: New. * gdb.threads/non-ldr-exc-4.exp: New. --- gdb/infrun.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'gdb/infrun.c') 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) -- cgit v1.1