static ptid_t child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { int save_errno; int status; char *execd_pathname = NULL; int exit_status; int syscall_id; enum target_waitkind kind; int pid; do { set_sigint_trap (); /* Causes SIGINT to be passed on to the attached process. */ set_sigio_trap (); pid = wait (&status); save_errno = errno; clear_sigio_trap (); clear_sigint_trap (); if (pid == -1) { if (save_errno == EINTR) continue; fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", safe_strerror (save_errno)); /* Claim it exited with unknown signal. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; return pid_to_ptid (-1); } /* Did it exit? */ if (target_has_exited (pid, status, &exit_status)) { /* ??rehrauer: For now, ignore this. */ continue; } if (!target_thread_alive (pid_to_ptid (pid))) { ourstatus->kind = TARGET_WAITKIND_SPURIOUS; return pid_to_ptid (pid); } } while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ store_waitstatus (ourstatus, status); return pid_to_ptid (pid); }
ptid_t child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { int save_errno; int status; char *execd_pathname = NULL; int exit_status; int related_pid; int syscall_id; enum target_waitkind kind; int pid; if (saved_vfork_state == STATE_FAKE_EXEC) { saved_vfork_state = STATE_NONE; ourstatus->kind = TARGET_WAITKIND_EXECD; ourstatus->value.execd_pathname = saved_child_execd_pathname; return inferior_ptid; } do { set_sigint_trap (); /* Causes SIGINT to be passed on to the attached process. */ set_sigio_trap (); pid = ptrace_wait (inferior_ptid, &status); save_errno = errno; clear_sigio_trap (); clear_sigint_trap (); if (pid == -1) { if (save_errno == EINTR) continue; fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", safe_strerror (save_errno)); /* Claim it exited with unknown signal. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; return pid_to_ptid (-1); } /* Did it exit? */ if (target_has_exited (pid, status, &exit_status)) { /* ??rehrauer: For now, ignore this. */ continue; } if (!target_thread_alive (pid_to_ptid (pid))) { ourstatus->kind = TARGET_WAITKIND_SPURIOUS; return pid_to_ptid (pid); } if (hpux_has_forked (pid, &related_pid)) { /* Ignore the parent's fork event. */ if (pid == PIDGET (inferior_ptid)) { ourstatus->kind = TARGET_WAITKIND_IGNORE; return inferior_ptid; } /* If this is the child's fork event, report that the process has forked. */ if (related_pid == PIDGET (inferior_ptid)) { ourstatus->kind = TARGET_WAITKIND_FORKED; ourstatus->value.related_pid = pid; return inferior_ptid; } } if (hpux_has_vforked (pid, &related_pid)) { if (pid == PIDGET (inferior_ptid)) { if (saved_vfork_state == STATE_GOT_CHILD) saved_vfork_state = STATE_GOT_PARENT; else if (saved_vfork_state == STATE_GOT_EXEC) saved_vfork_state = STATE_FAKE_EXEC; else fprintf_unfiltered (gdb_stdout, "hppah: parent vfork: confused\n"); } else if (related_pid == PIDGET (inferior_ptid)) { if (saved_vfork_state == STATE_NONE) saved_vfork_state = STATE_GOT_CHILD; else fprintf_unfiltered (gdb_stdout, "hppah: child vfork: confused\n"); } else fprintf_unfiltered (gdb_stdout, "hppah: unknown vfork: confused\n"); if (saved_vfork_state == STATE_GOT_CHILD) { child_post_startup_inferior (pid_to_ptid (pid)); detach_breakpoints (pid); #ifdef SOLIB_REMOVE_INFERIOR_HOOK SOLIB_REMOVE_INFERIOR_HOOK (pid); #endif child_resume (pid_to_ptid (pid), 0, TARGET_SIGNAL_0); ourstatus->kind = TARGET_WAITKIND_IGNORE; return pid_to_ptid (related_pid); } else if (saved_vfork_state == STATE_FAKE_EXEC) { ourstatus->kind = TARGET_WAITKIND_VFORKED; ourstatus->value.related_pid = related_pid; return pid_to_ptid (pid); } else { /* We saw the parent's vfork, but we haven't seen the exec yet. Wait for it, for simplicity's sake. It should be pending. */ saved_vfork_pid = related_pid; ourstatus->kind = TARGET_WAITKIND_IGNORE; return pid_to_ptid (pid); } } if (hpux_has_execd (pid, &execd_pathname)) { /* On HP-UX, events associated with a vforking inferior come in threes: a vfork event for the child (always first), followed a vfork event for the parent and an exec event for the child. The latter two can come in either order. Make sure we get both. */ if (saved_vfork_state != STATE_NONE) { if (saved_vfork_state == STATE_GOT_CHILD) { saved_vfork_state = STATE_GOT_EXEC; /* On HP/UX with ptrace, the child must be resumed before the parent vfork event is delivered. A single-step suffices. */ if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ()) target_resume (pid_to_ptid (pid), 1, TARGET_SIGNAL_0); ourstatus->kind = TARGET_WAITKIND_IGNORE; } else if (saved_vfork_state == STATE_GOT_PARENT) { saved_vfork_state = STATE_FAKE_EXEC; ourstatus->kind = TARGET_WAITKIND_VFORKED; ourstatus->value.related_pid = saved_vfork_pid; } else fprintf_unfiltered (gdb_stdout, "hppa: exec: unexpected state\n"); saved_child_execd_pathname = execd_pathname; return inferior_ptid; } /* Are we ignoring initial exec events? (This is likely because we're in the process of starting up the inferior, and another (older) mechanism handles those.) If so, we'll report this as a regular stop, not an exec. */ if (inferior_ignoring_startup_exec_events) { inferior_ignoring_startup_exec_events--; } else { ourstatus->kind = TARGET_WAITKIND_EXECD; ourstatus->value.execd_pathname = execd_pathname; return pid_to_ptid (pid); } } /* All we must do with these is communicate their occurrence to wait_for_inferior... */ if (hpux_has_syscall_event (pid, &kind, &syscall_id)) { ourstatus->kind = kind; ourstatus->value.syscall_id = syscall_id; return pid_to_ptid (pid); } /*## } while (pid != PIDGET (inferior_ptid)); ## *//* Some other child died or stopped */ /* hack for thread testing */ } while ((pid != PIDGET (inferior_ptid)) && not_same_real_pid); /*## */ store_waitstatus (ourstatus, status); return pid_to_ptid (pid); }
static ptid_t child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { int save_errno; int status; char *execd_pathname = NULL; int exit_status; int related_pid; int syscall_id; enum target_waitkind kind; int pid; do { set_sigint_trap (); /* Causes SIGINT to be passed on to the attached process. */ set_sigio_trap (); pid = ptrace_wait (inferior_ptid, &status); save_errno = errno; clear_sigio_trap (); clear_sigint_trap (); if (pid == -1) { if (save_errno == EINTR) continue; fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", safe_strerror (save_errno)); /* Claim it exited with unknown signal. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; return pid_to_ptid (-1); } /* Did it exit? */ if (target_has_exited (pid, status, &exit_status)) { /* ??rehrauer: For now, ignore this. */ continue; } if (!target_thread_alive (pid_to_ptid (pid))) { ourstatus->kind = TARGET_WAITKIND_SPURIOUS; return pid_to_ptid (pid); } if (target_has_forked (pid, &related_pid) && ((pid == PIDGET (inferior_ptid)) || (related_pid == PIDGET (inferior_ptid)))) { ourstatus->kind = TARGET_WAITKIND_FORKED; ourstatus->value.related_pid = related_pid; return pid_to_ptid (pid); } if (target_has_vforked (pid, &related_pid) && ((pid == PIDGET (inferior_ptid)) || (related_pid == PIDGET (inferior_ptid)))) { ourstatus->kind = TARGET_WAITKIND_VFORKED; ourstatus->value.related_pid = related_pid; return pid_to_ptid (pid); } if (target_has_execd (pid, &execd_pathname)) { /* Are we ignoring initial exec events? (This is likely because we're in the process of starting up the inferior, and another (older) mechanism handles those.) If so, we'll report this as a regular stop, not an exec. */ if (inferior_ignoring_startup_exec_events) { inferior_ignoring_startup_exec_events--; } else { ourstatus->kind = TARGET_WAITKIND_EXECD; ourstatus->value.execd_pathname = execd_pathname; return pid_to_ptid (pid); } } /* All we must do with these is communicate their occurrence to wait_for_inferior... */ if (target_has_syscall_event (pid, &kind, &syscall_id)) { ourstatus->kind = kind; ourstatus->value.syscall_id = syscall_id; return pid_to_ptid (pid); } /*## } while (pid != PIDGET (inferior_ptid)); ## *//* Some other child died or stopped */ /* hack for thread testing */ } while ((pid != PIDGET (inferior_ptid)) && not_same_real_pid); /*## */ store_waitstatus (ourstatus, status); return pid_to_ptid (pid); }