* Make linux_nat.c's target_wait always respect TARGET_WNOHANG.
@ 2009-10-09 1:53 Pedro Alves
2009-10-10 5:20 ` Hui Zhu
0 siblings, 1 reply; 2+ messages in thread
From: Pedro Alves @ 2009-10-09 1:53 UTC (permalink / raw)
To: gdb-patches
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)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Make linux_nat.c's target_wait always respect TARGET_WNOHANG.
2009-10-09 1:53 Make linux_nat.c's target_wait always respect TARGET_WNOHANG Pedro Alves
@ 2009-10-10 5:20 ` Hui Zhu
0 siblings, 0 replies; 2+ messages in thread
From: Hui Zhu @ 2009-10-10 5:20 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
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)
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-10-10 5:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-09 1:53 Make linux_nat.c's target_wait always respect TARGET_WNOHANG Pedro Alves
2009-10-10 5:20 ` Hui Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox