diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/config/nm-linux.h | 5 | ||||
-rw-r--r-- | gdb/linux-nat.c | 38 | ||||
-rw-r--r-- | gdb/linux-nat.h | 2 | ||||
-rw-r--r-- | gdb/linux-thread-db.c | 15 |
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) |