summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/config/nm-linux.h5
-rw-r--r--gdb/linux-nat.c38
-rw-r--r--gdb/linux-nat.h2
-rw-r--r--gdb/linux-thread-db.c15
5 files changed, 47 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c24ebc65cb5..4d248ab6fed 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/config/nm-linux.h b/gdb/config/nm-linux.h
index b79875eb680..7c06862c9f9 100644
--- a/gdb/config/nm-linux.h
+++ b/gdb/config/nm-linux.h
@@ -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)
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index b0b9cf32b93..c0e6dc1a51c 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -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
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index 5b39abfcb04..d3f4f3974b7 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -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 *),
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 4b0aef7951f..94774c5de4b 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -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)