static LONGEST sol_thread_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, void *readbuf, const void *writebuf, ULONGEST offset, LONGEST len) { int retval; struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ if (target_has_execution) retval = procfs_ops.to_xfer_partial (ops, object, annex, readbuf, writebuf, offset, len); else retval = orig_core_ops.to_xfer_partial (ops, object, annex, readbuf, writebuf, offset, len); do_cleanups (old_chain); return retval; }
static int sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, struct mem_attrib *attrib, struct target_ops *target) { int retval; struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ if (target_has_execution) retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target); else retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target); do_cleanups (old_chain); return retval; }
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); }
static ps_err_e rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, char *buf, int size) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ #if defined (__sparcv9) /* For Sparc64 cross Sparc32, make sure the address has not been accidentally sign-extended (or whatever) to beyond 32 bits. */ if (bfd_get_arch_size (exec_bfd) == 32) addr &= 0xffffffff; #endif while (size > 0) { int cc; /* FIXME: passing 0 as attrib argument. */ if (target_has_execution) cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &procfs_ops); else cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &core_ops); if (cc < 0) { if (dowrite == 0) print_sys_errmsg ("rw_common (): read", errno); else print_sys_errmsg ("rw_common (): write", errno); do_cleanups (old_chain); return PS_ERR; } else if (cc == 0) { if (dowrite == 0) warning ("rw_common (): unable to read at addr 0x%lx", (long) addr); else warning ("rw_common (): unable to write at addr 0x%lx", (long) addr); do_cleanups (old_chain); return PS_ERR; } size -= cc; buf += cc; } do_cleanups (old_chain); return PS_OK; }