* linux-nat.c (lin_lwp_attach_lwp): Return a status. Do not
authorDaniel Jacobowitz <drow@false.org>
Sun, 31 Dec 2006 21:04:51 +0000 (21:04 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sun, 31 Dec 2006 21:04:51 +0000 (21:04 +0000)
add the LWP to our list until we are attached.  Warn instead
of erroring if the attach fails.
* linux-nat.h (lin_lwp_attach_lwp): New prototype.
* linux-thread-db.c (attach_thread): Call lin_lwp_attach_lwp
directly.  Do not add the thread to our list until we are
successfully attached.
* config/nm-linux.h (lin_lwp_attach_lwp, ATTACH_LWP): Delete.

gdb/ChangeLog
gdb/config/nm-linux.h
gdb/linux-nat.c
gdb/linux-nat.h
gdb/linux-thread-db.c

index c24ebc6..4d248ab 100644 (file)
@@ -1,5 +1,16 @@
 2006-12-31  Daniel Jacobowitz  <dan@codesourcery.com>
 
+       * linux-nat.c (lin_lwp_attach_lwp): Return a status.  Do not
+       add the LWP to our list until we are attached.  Warn instead
+       of erroring if the attach fails.
+       * linux-nat.h (lin_lwp_attach_lwp): New prototype.
+       * linux-thread-db.c (attach_thread): Call lin_lwp_attach_lwp
+       directly.  Do not add the thread to our list until we are
+       successfully attached.
+       * config/nm-linux.h (lin_lwp_attach_lwp, ATTACH_LWP): Delete.
+
+2006-12-31  Daniel Jacobowitz  <dan@codesourcery.com>
+
        * configure.ac: Add tests for TD_VERSION and TD_NOTLS.
        * linux-thread-db.c (thread_db_err_str): Recognize TD_NOTALLOC,
        TD_VERSION, and TD_NOTLS.
index b79875e..7c06862 100644 (file)
@@ -1,6 +1,6 @@
 /* Native support for GNU/Linux.
 
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -25,9 +25,6 @@ struct target_ops;
 /* GNU/Linux is SVR4-ish but its /proc file system isn't.  */
 #undef USE_PROC_FS
 
-extern void lin_lwp_attach_lwp (ptid_t ptid, int verbose);
-#define ATTACH_LWP(ptid, verbose) lin_lwp_attach_lwp ((ptid), (verbose))
-
 extern void lin_thread_get_thread_signals (sigset_t *mask);
 #define GET_THREAD_SIGNALS(mask) lin_thread_get_thread_signals (mask)
 
index b0b9cf3..c0e6dc1 100644 (file)
@@ -915,12 +915,13 @@ exit_lwp (struct lwp_info *lp)
 
 /* Attach to the LWP specified by PID.  If VERBOSE is non-zero, print
    a message telling the user that a new LWP has been added to the
-   process.  */
+   process.  Return 0 if successful or -1 if the new LWP could not
+   be attached.  */
 
-void
+int
 lin_lwp_attach_lwp (ptid_t ptid, int verbose)
 {
-  struct lwp_info *lp, *found_lp;
+  struct lwp_info *lp;
 
   gdb_assert (is_lwp (ptid));
 
@@ -932,12 +933,7 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose)
       sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
     }
 
-  if (verbose)
-    printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
-
-  found_lp = lp = find_lwp_pid (ptid);
-  if (lp == NULL)
-    lp = add_lwp (ptid);
+  lp = find_lwp_pid (ptid);
 
   /* We assume that we're already attached to any LWP that has an id
      equal to the overall process id, and to any LWP that is already
@@ -945,14 +941,25 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose)
      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 (GET_LWP (ptid) != GET_PID (ptid) && found_lp == NULL)
+  if (GET_LWP (ptid) != GET_PID (ptid) && lp == NULL)
     {
       pid_t pid;
       int status;
 
       if (ptrace (PTRACE_ATTACH, GET_LWP (ptid), 0, 0) < 0)
-       error (_("Can't attach %s: %s"), target_pid_to_str (ptid),
-              safe_strerror (errno));
+       {
+         /* 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 2.6.19, a kernel
+            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 (lp == NULL)
+       lp = add_lwp (ptid);
 
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
@@ -990,8 +997,15 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose)
          threads.  Note that this won't have already been done since
          the main thread will have, we assume, been stopped by an
          attach from a different layer.  */
+      if (lp == NULL)
+       lp = add_lwp (ptid);
       lp->stopped = 1;
     }
+
+  if (verbose)
+    printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
+
+  return 0;
 }
 
 static void
index 5b39abf..d3f4f39 100644 (file)
@@ -80,6 +80,8 @@ extern void linux_enable_event_reporting (ptid_t ptid);
 extern ptid_t linux_handle_extended_wait (int pid, int status,
                                          struct target_waitstatus *ourstatus);
 
+extern int lin_lwp_attach_lwp (ptid_t ptid, int verbose);
+
 /* Iterator function for lin-lwp's lwp list.  */
 struct lwp_info *iterate_over_lwps (int (*callback) (struct lwp_info *, 
                                                     void *), 
index 4b0aef7..94774c5 100644 (file)
@@ -690,6 +690,13 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
 
   check_thread_signals ();
 
+  if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
+    return;                    /* A zombie thread -- do not attach.  */
+
+  /* Under GNU/Linux, we have to attach to each and every thread.  */
+  if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0) < 0)
+    return;
+
   /* Add the thread to GDB's thread list.  */
   tp = add_thread (ptid);
   tp->private = xmalloc (sizeof (struct private_thread_info));
@@ -698,14 +705,6 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
   if (verbose)
     printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
 
-  if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
-    return;                    /* A zombie thread -- do not attach.  */
-
-  /* Under GNU/Linux, we have to attach to each and every thread.  */
-#ifdef ATTACH_LWP
-  ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
-#endif
-
   /* Enable thread event reporting for this thread.  */
   err = td_thr_event_enable_p (th_p, 1);
   if (err != TD_OK)