From 287369626f415a12f53989914dc0499b6c96d1aa Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 9 Oct 2009 01:57:12 +0000 Subject: [PATCH] * linux-nat.c (linux_nat_wait_1): Bail out, if TARGET_WNOHANG and we found no event while waiting for a specific LWP. * infrun.c (handle_inferior_event): Handle TARGET_WAITKIND_IGNORE before anything else. --- gdb/ChangeLog | 7 ++++++ gdb/infrun.c | 62 ++++++++++++++++++++++++------------------------- gdb/linux-nat.c | 11 +++++++++ 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 77987ca15f..c18ed8011c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2009-10-09 Pedro Alves + + * linux-nat.c (linux_nat_wait_1): Bail out, if TARGET_WNOHANG and + we found no event while waiting for a specific LWP. + * infrun.c (handle_inferior_event): Handle TARGET_WAITKIND_IGNORE + before anything else. + 2009-10-09 Pedro Alves * procfs.c (procfs_make_note_section): Always output a NT_PSTATUS diff --git a/gdb/infrun.c b/gdb/infrun.c index 4ce07d9dcf..203ab5d5ca 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2443,9 +2443,25 @@ handle_inferior_event (struct execution_control_state *ecs) struct symtab_and_line stop_pc_sal; enum stop_kind stop_soon; + if (ecs->ws.kind == TARGET_WAITKIND_IGNORE) + { + /* We had an event in the inferior, but we are not interested in + handling it at this level. The lower layers have already + done what needs to be done, if anything. + + One of the possible circumstances for this is when the + inferior produces output for the console. The inferior has + not stopped, and we are ignoring the event. Another possible + circumstance is any event which the lower level knows will be + reported multiple times without an intervening resume. */ + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n"); + prepare_to_wait (ecs); + return; + } + if (ecs->ws.kind != TARGET_WAITKIND_EXITED - && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED - && ecs->ws.kind != TARGET_WAITKIND_IGNORE) + && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) { struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid)); gdb_assert (inf); @@ -2479,22 +2495,19 @@ handle_inferior_event (struct execution_control_state *ecs) /* Dependent on the current PC value modified by adjust_pc_after_break. */ reinit_frame_cache (); - if (ecs->ws.kind != TARGET_WAITKIND_IGNORE) - { - breakpoint_retire_moribund (); + breakpoint_retire_moribund (); - /* Mark the non-executing threads accordingly. In all-stop, all - threads of all processes are stopped when we get any event - reported. In non-stop mode, only the event thread stops. If - we're handling a process exit in non-stop mode, there's - nothing to do, as threads of the dead process are gone, and - threads of any other process were left running. */ - if (!non_stop) - set_executing (minus_one_ptid, 0); - else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED - && ecs->ws.kind != TARGET_WAITKIND_EXITED) - set_executing (inferior_ptid, 0); - } + /* Mark the non-executing threads accordingly. In all-stop, all + threads of all processes are stopped when we get any event + reported. In non-stop mode, only the event thread stops. If + we're handling a process exit in non-stop mode, there's nothing + to do, as threads of the dead process are gone, and threads of + any other process were left running. */ + if (!non_stop) + set_executing (minus_one_ptid, 0); + else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED + && ecs->ws.kind != TARGET_WAITKIND_EXITED) + set_executing (inferior_ptid, 0); switch (infwait_state) { @@ -2777,21 +2790,6 @@ handle_inferior_event (struct execution_control_state *ecs) print_stop_reason (NO_HISTORY, 0); stop_stepping (ecs); return; - - /* We had an event in the inferior, but we are not interested - in handling it at this level. The lower layers have already - done what needs to be done, if anything. - - One of the possible circumstances for this is when the - inferior produces output for the console. The inferior has - not stopped, and we are ignoring the event. Another possible - circumstance is any event which the lower level knows will be - reported multiple times without an intervening resume. */ - case TARGET_WAITKIND_IGNORE: - if (debug_infrun) - fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n"); - prepare_to_wait (ecs); - return; } if (ecs->new_thread_event) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index f4f843bf0e..bde73117de 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3255,6 +3255,17 @@ retry: sigsuspend (&suspend_mask); } } + else if (target_options & TARGET_WNOHANG) + { + /* No interesting event for PID yet. */ + ourstatus->kind = TARGET_WAITKIND_IGNORE; + + if (debug_linux_nat_async) + fprintf_unfiltered (gdb_stdlog, "LLW: exit (ignore)\n"); + + restore_child_signals_mask (&prev_mask); + return minus_one_ptid; + } /* We shouldn't end up here unless we want to try again. */ gdb_assert (lp == NULL);