This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Make linux_nat.c's target_wait always respect TARGET_WNOHANG.


Thanks for your patch, Pedro.

Hui

On Fri, Oct 9, 2009 at 09:53, Pedro Alves <pedro@codesourcery.com> wrote:
> Moving from <http://sourceware.org/ml/gdb/2009-10/msg00167.html>.
>
> This patch fixes an issue Hui noticed. ?linux_nat_wait_1
> wasn't respecting the TARGET_WNOHANG option in the case of waiting
> for a specific lwpid.
>
> We have a related infrun bug. ?If gdb is thread hoping, or other
> situation when waiton_ptid is set (infwait_state != infwait_normal_state),
> a TARGET_WAITKIND_IGNORE would reset infwait_state and waiton_ptid.
>
> Tested on x86_64-unknown-linux-gnu native sync and async modes.
>
> I'm checking this in. ?Thanks Hui.
>
> --
> Pedro Alves
>
> 2009-10-09 ?Pedro Alves ?<pedro@codesourcery.com>
>
> ? ? ? ?* 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/infrun.c ? ?| ? 62 +++++++++++++++++++++++++++-----------------------------
> ?gdb/linux-nat.c | ? 11 +++++++++
> ?2 files changed, 41 insertions(+), 32 deletions(-)
>
> Index: src/gdb/linux-nat.c
> ===================================================================
> --- src.orig/gdb/linux-nat.c ? ?2009-10-09 02:23:48.000000000 +0100
> +++ src/gdb/linux-nat.c 2009-10-09 02:42:37.000000000 +0100
> @@ -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);
> Index: src/gdb/infrun.c
> ===================================================================
> --- src.orig/gdb/infrun.c ? ? ? 2009-10-09 02:23:48.000000000 +0100
> +++ src/gdb/infrun.c ? ?2009-10-09 02:52:29.000000000 +0100
> @@ -2443,9 +2443,25 @@ handle_inferior_event (struct execution_
> ? 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_
> ? /* 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_
> ? ? ? 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)
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]