aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2009-10-09 01:57:12 +0000
committerPedro Alves <palves@redhat.com>2009-10-09 01:57:12 +0000
commit287369626f415a12f53989914dc0499b6c96d1aa (patch)
treefa8288f856b36c63ad94c80b6fc86ba848c2a428
parent651c8d2d6c30c4d2178988e5c48fdad2116982ed (diff)
downloadgdb-287369626f415a12f53989914dc0499b6c96d1aa.zip
gdb-287369626f415a12f53989914dc0499b6c96d1aa.tar.gz
gdb-287369626f415a12f53989914dc0499b6c96d1aa.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/infrun.c64
-rw-r--r--gdb/linux-nat.c11
3 files changed, 49 insertions, 33 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 77987ca..c18ed80 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
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.
+
+2009-10-09 Pedro Alves <pedro@codesourcery.com>
+
* procfs.c (procfs_make_note_section): Always output a NT_PSTATUS
note when NEW_PROC_API is defined.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4ce07d9..203ab5d 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 ();
-
- /* 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);
- }
+ 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);
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 f4f843b..bde7311 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);