This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Disable thread specific breakpoints when thread dies
- From: Andrew STUBBS <andrew dot stubbs at st dot com>
- To: Daniel Jacobowitz <drow at false dot org>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Mon, 16 Jan 2006 16:16:43 +0000
- Subject: Re: [PATCH] Disable thread specific breakpoints when thread dies
- References: <43723446.7000903@st.com> <20051113184515.GG3599@nevyn.them.org> <437875B0.4000007@st.com> <20051114155659.GA25717@nevyn.them.org> <437A19DE.6040905@st.com> <437B47A1.4040705@st.com> <20051117034811.GB3057@nevyn.them.org> <437CA66B.9060201@st.com> <20060112162659.GA16141@nevyn.them.org> <43C7E466.9080703@st.com> <20060114160611.GA12603@nevyn.them.org> <43CB97A2.20205@st.com>
Andrew STUBBS wrote:
Now onto figuring out why it doesn't work....
The smoking gun seems to be here:
[From linux-thread-db.c]
static void
detach_thread (ptid_t ptid, int verbose)
{
struct thread_info *thread_info;
if (verbose)
printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
/* Don't delete the thread now, because it still reports as active
until it has executed a few instructions after the event
breakpoint - if we deleted it now, "info threads" would cause us
to re-attach to it. Just mark it as having had a TD_DEATH
event. This means that we won't delete it from our thread list
until we notice that it's dead (via prune_threads), or until
something re-uses its thread ID. */
thread_info = find_thread_pid (ptid);
gdb_assert (thread_info != NULL);
thread_info->private->dying = 1;
}
The attached patch fixes the problem, but I don't know if it does it the
best way.
What do you think?
Andrew Stubbs
2006-01-16 Amdrew Stubbs <andrew.stubbs@st.com>
* gdbthread.h (prune_threads): Add prototype.
* infrun.c (normal_stop): Call prune_threads().
* thread.c (prune_threads): Remove 'static'.
Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h 2006-01-16 16:08:57.000000000 +0000
+++ src/gdb/gdbthread.h 2006-01-16 16:13:57.000000000 +0000
@@ -80,6 +80,9 @@ extern struct thread_info *add_thread (p
/* Delete an existing thread list entry. */
extern void delete_thread (ptid_t);
+/* Delete all dead threads from the list. */
+extern void prune_threads (void);
+
/* Delete a step_resume_breakpoint from the thread database. */
extern void delete_step_resume_breakpoint (void *);
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c 2006-01-16 16:08:57.000000000 +0000
+++ src/gdb/infrun.c 2006-01-16 16:13:57.000000000 +0000
@@ -3037,6 +3037,9 @@ Further execution is probably impossible
if (stopped_by_random_signal)
disable_current_display ();
+ /* Delete any threads which have died. */
+ prune_threads ();
+
/* Don't print a message if in the middle of doing a "step n"
operation for n > 1 */
if (step_multi && stop_step)
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c 2006-01-16 16:08:57.000000000 +0000
+++ src/gdb/thread.c 2006-01-16 16:13:57.000000000 +0000
@@ -64,7 +64,6 @@ static void info_threads_command (char *
static void thread_apply_command (char *, int);
static void restore_current_thread (ptid_t);
static void switch_to_thread (ptid_t ptid);
-static void prune_threads (void);
void
delete_step_resume_breakpoint (void *arg)
@@ -382,7 +381,7 @@ thread_alive (struct thread_info *tp)
return 1;
}
-static void
+void
prune_threads (void)
{
struct thread_info *tp, *next;