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); }
static ptid_t rs6000_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { pid_t pid; int status, save_errno; do { set_sigint_trap (); set_sigio_trap (); do { pid = waitpid (ptid_get_pid (ptid), &status, 0); save_errno = errno; } while (pid == -1 && errno == EINTR); clear_sigio_trap (); clear_sigint_trap (); if (pid == -1) { 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 minus_one_ptid; } /* Ignore terminated detached child processes. */ if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) pid = -1; } while (pid == -1); /* AIX has a couple of strange returns from wait(). */ /* stop after load" status. */ if (status == 0x57c) ourstatus->kind = TARGET_WAITKIND_LOADED; /* signal 0. I have no idea why wait(2) returns with this status word. */ else if (status == 0x7f) ourstatus->kind = TARGET_WAITKIND_SPURIOUS; /* A normal waitstatus. Let the usual macros deal with it. */ else store_waitstatus (ourstatus, status); return pid_to_ptid (pid); }
static ptid_t inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { pid_t pid; int status, save_errno; do { set_sigint_trap (); set_sigio_trap (); do { pid = waitpid (ptid_get_pid (ptid), &status, 0); save_errno = errno; } while (pid == -1 && errno == EINTR); clear_sigio_trap (); clear_sigint_trap (); if (pid == -1) { 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 minus_one_ptid; } /* Ignore terminated detached child processes. */ if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) pid = -1; } while (pid == -1); #ifdef PT_GET_PROCESS_STATE if (WIFSTOPPED (status)) { ptrace_state_t pe; pid_t fpid; if (ptrace (PT_GET_PROCESS_STATE, pid, (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) perror_with_name (("ptrace")); switch (pe.pe_report_event) { case PTRACE_FORK: ourstatus->kind = TARGET_WAITKIND_FORKED; ourstatus->value.related_pid = pe.pe_other_pid; /* Make sure the other end of the fork is stopped too. */ fpid = waitpid (pe.pe_other_pid, &status, 0); if (fpid == -1) perror_with_name (("waitpid")); if (ptrace (PT_GET_PROCESS_STATE, fpid, (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) perror_with_name (("ptrace")); gdb_assert (pe.pe_report_event == PTRACE_FORK); gdb_assert (pe.pe_other_pid == pid); if (fpid == ptid_get_pid (inferior_ptid)) { ourstatus->value.related_pid = pe.pe_other_pid; return pid_to_ptid (fpid); } return pid_to_ptid (pid); } } #endif 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); }