-/* Attach to the LWP specified by PID. Return 0 if successful, -1 if
- the new LWP could not be attached, or 1 if we're already auto
- attached to this thread, but haven't processed the
- PTRACE_EVENT_CLONE event of its parent thread, so we just ignore
- its existance, without considering it an error. */
-
-int
-lin_lwp_attach_lwp (ptid_t ptid)
-{
- struct lwp_info *lp;
- int lwpid;
-
- gdb_assert (ptid_lwp_p (ptid));
-
- lp = find_lwp_pid (ptid);
- lwpid = ptid_get_lwp (ptid);
-
- /* We assume that we're already attached to any LWP that is already
- in our list of LWPs. If we're not seeing exit events from threads
- and we've had PID wraparound since we last tried to stop all threads,
- this assumption might be wrong; fortunately, this is very unlikely
- to happen. */
- if (lp == NULL)
- {
- int status, cloned = 0, signalled = 0;
-
- if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) < 0)
- {
- if (linux_supports_tracefork ())
- {
- /* If we haven't stopped all threads when we get here,
- we may have seen a thread listed in thread_db's list,
- but not processed the PTRACE_EVENT_CLONE yet. If
- that's the case, ignore this new thread, and let
- normal event handling discover it later. */
- if (in_pid_list_p (stopped_pids, lwpid))
- {
- /* We've already seen this thread stop, but we
- haven't seen the PTRACE_EVENT_CLONE extended
- event yet. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: attach failed, but already seen "
- "this thread %s stop\n",
- target_pid_to_str (ptid));
- return 1;
- }
- else
- {
- int new_pid;
- int status;
-
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: attach failed, and haven't seen "
- "this thread %s stop yet\n",
- target_pid_to_str (ptid));
-
- /* We may or may not be attached to the LWP already.
- Try waitpid on it. If that errors, we're not
- attached to the LWP yet. Otherwise, we're
- already attached. */
- gdb_assert (lwpid > 0);
- new_pid = my_waitpid (lwpid, &status, WNOHANG);
- if (new_pid == -1 && errno == ECHILD)
- new_pid = my_waitpid (lwpid, &status, __WCLONE | WNOHANG);
- if (new_pid != -1)
- {
- if (new_pid == 0)
- {
- /* The child hasn't stopped for its initial
- SIGSTOP stop yet. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: child hasn't "
- "stopped yet\n");
- }
- else if (WIFSTOPPED (status))
- {
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: adding to stopped_pids\n");
- add_to_pid_list (&stopped_pids, lwpid, status);
- }
- return 1;
- }
- }
- }
-
- /* If we fail to attach to the thread, issue a warning,
- but continue. One way this can happen is if thread
- creation is interrupted; as of Linux kernel 2.6.19, a
- bug may place threads in the thread list and then fail
- to create them. */
- warning (_("Can't attach %s: %s"), target_pid_to_str (ptid),
- safe_strerror (errno));
- return -1;
- }
-
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: PTRACE_ATTACH %s, 0, 0 (OK)\n",
- target_pid_to_str (ptid));
-
- status = linux_nat_post_attach_wait (ptid, 0, &cloned, &signalled);
- if (!WIFSTOPPED (status))
- return 1;
-
- lp = add_lwp (ptid);
- lp->stopped = 1;
- lp->last_resume_kind = resume_stop;
- lp->cloned = cloned;
- lp->signalled = signalled;
- if (WSTOPSIG (status) != SIGSTOP)
- {
- lp->resumed = 1;
- lp->status = status;
- }
-
- target_post_attach (ptid_get_lwp (lp->ptid));
-
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "LLAL: waitpid %s received %s\n",
- target_pid_to_str (ptid),
- status_to_str (status));
- }
- }
-
- return 0;
-}
-
-static void
-linux_nat_create_inferior (struct target_ops *ops,
- char *exec_file, char *allargs, char **env,
- int from_tty)