static pid_t do_attach (pid_t pid) { procfs_status status; struct sigevent event; if (nto_inferior.ctl_fd != -1) { close (nto_inferior.ctl_fd); init_nto_inferior (&nto_inferior); } xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid); nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR); if (nto_inferior.ctl_fd == -1) { TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path); init_nto_inferior (&nto_inferior); return -1; } if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK) { do_detach (); return -1; } nto_inferior.pid = pid; /* Define a sigevent for process stopped notification. */ event.sigev_notify = SIGEV_SIGNAL_THREAD; event.sigev_signo = SIGUSR1; event.sigev_code = 0; event.sigev_value.sival_ptr = NULL; event.sigev_priority = -1; devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK && (status.flags & _DEBUG_FLAG_STOPPED)) { ptid_t ptid; struct process_info *proc; kill (pid, SIGCONT); ptid = ptid_build (status.pid, status.tid, 0); the_low_target.arch_setup (); proc = add_process (status.pid, 1); proc->tdesc = nto_tdesc; TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid, ptid_get_lwp (ptid)); nto_find_new_threads (&nto_inferior); } else { do_detach (); return -1; } return pid; }
static ptid_t nto_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int target_options) { sigset_t set; siginfo_t info; procfs_status status; const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY); TRACE ("%s\n", __func__); ourstatus->kind = TARGET_WAITKIND_SPURIOUS; sigemptyset (&set); sigaddset (&set, SIGUSR1); devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); while (!(status.flags & _DEBUG_FLAG_ISTOP)) { sigwaitinfo (&set, &info); devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); } nto_find_new_threads (&nto_inferior); if (status.flags & _DEBUG_FLAG_SSTEP) { TRACE ("SSTEP\n"); ourstatus->kind = TARGET_WAITKIND_STOPPED; ourstatus->value.sig = TARGET_SIGNAL_TRAP; } /* Was it a breakpoint? */ else if (status.flags & trace_mask) { TRACE ("STOPPED\n"); ourstatus->kind = TARGET_WAITKIND_STOPPED; ourstatus->value.sig = TARGET_SIGNAL_TRAP; } else if (status.flags & _DEBUG_FLAG_ISTOP) { TRACE ("ISTOP\n"); switch (status.why) { case _DEBUG_WHY_SIGNALLED: TRACE (" SIGNALLED\n"); ourstatus->kind = TARGET_WAITKIND_STOPPED; ourstatus->value.sig = target_signal_from_host (status.info.si_signo); nto_inferior.exit_signo = ourstatus->value.sig; break; case _DEBUG_WHY_FAULTED: TRACE (" FAULTED\n"); ourstatus->kind = TARGET_WAITKIND_STOPPED; if (status.info.si_signo == SIGTRAP) { ourstatus->value.sig = 0; nto_inferior.exit_signo = 0; } else { ourstatus->value.sig = target_signal_from_host (status.info.si_signo); nto_inferior.exit_signo = ourstatus->value.sig; } break; case _DEBUG_WHY_TERMINATED: { int waitval = 0; TRACE (" TERMINATED\n"); waitpid (ptid_get_pid (ptid), &waitval, WNOHANG); if (nto_inferior.exit_signo) { /* Abnormal death. */ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; ourstatus->value.sig = nto_inferior.exit_signo; } else { /* Normal death. */ ourstatus->kind = TARGET_WAITKIND_EXITED; ourstatus->value.integer = WEXITSTATUS (waitval); } nto_inferior.exit_signo = 0; break; } case _DEBUG_WHY_REQUESTED: TRACE ("REQUESTED\n"); /* We are assuming a requested stop is due to a SIGINT. */ ourstatus->kind = TARGET_WAITKIND_STOPPED; ourstatus->value.sig = TARGET_SIGNAL_INT; nto_inferior.exit_signo = 0; break; } } return ptid_build (status.pid, status.tid, 0); }