aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gdbserver/ChangeLog11
-rw-r--r--gdb/gdbserver/linux-low.c22
-rw-r--r--gdb/gdbserver/thread-db.c20
3 files changed, 45 insertions, 8 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index bd819f0..3706a4f 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,14 @@
+2009-12-28 Pedro Alves <pedro@codesourcery.com>
+
+ * linux-low.c (linux_remove_process): Remove `detaching'
+ parameter. Don't release/detach from thread_db here.
+ (linux_kill): Release/detach from thread_db here, ...
+ (linux_detach): ... and here, before actually detaching.
+ (linux_wait_1): ... and here, when a process exits.
+ * thread-db.c (any_thread_of): New.
+ (thread_db_free): Switch the current inferior to a thread of the
+ passed in process.
+
2009-12-21 Doug Evans <dje@google.com>
* linux-x86-low.c: Delete outdated comment about Elf32_Phdr.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 8e91d2b..4c636e1 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -258,14 +258,10 @@ linux_add_process (int pid, int attached)
also freeing all private data. */
static void
-linux_remove_process (struct process_info *process, int detaching)
+linux_remove_process (struct process_info *process)
{
struct process_info_private *priv = process->private;
-#ifdef USE_THREAD_DB
- thread_db_free (process, detaching);
-#endif
-
free (priv->arch_private);
free (priv);
remove_process (process);
@@ -736,8 +732,11 @@ linux_kill (int pid)
lwpid = linux_wait_for_event (lwp->head.id, &wstat, __WALL);
} while (lwpid > 0 && WIFSTOPPED (wstat));
+#ifdef USE_THREAD_DB
+ thread_db_free (process, 0);
+#endif
delete_lwp (lwp);
- linux_remove_process (process, 0);
+ linux_remove_process (process);
return 0;
}
@@ -821,12 +820,16 @@ linux_detach (int pid)
if (process == NULL)
return -1;
+#ifdef USE_THREAD_DB
+ thread_db_free (process, 1);
+#endif
+
current_inferior =
(struct thread_info *) find_inferior (&all_threads, any_thread_of, &pid);
delete_all_breakpoints ();
find_inferior (&all_threads, linux_detach_one_lwp, &pid);
- linux_remove_process (process, 1);
+ linux_remove_process (process);
return 0;
}
@@ -1451,8 +1454,11 @@ retry:
int pid = pid_of (lwp);
struct process_info *process = find_process_pid (pid);
+#ifdef USE_THREAD_DB
+ thread_db_free (process, 0);
+#endif
delete_lwp (lwp);
- linux_remove_process (process, 0);
+ linux_remove_process (process);
current_inferior = NULL;
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index e169a50..a237b6d 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -755,6 +755,17 @@ thread_db_init (int use_events)
return 0;
}
+static int
+any_thread_of (struct inferior_list_entry *entry, void *args)
+{
+ int *pid_p = args;
+
+ if (ptid_get_pid (entry->id) == *pid_p)
+ return 1;
+
+ return 0;
+}
+
/* Disconnect from libthread_db and free resources. */
void
@@ -763,6 +774,8 @@ thread_db_free (struct process_info *proc, int detaching)
struct thread_db *thread_db = proc->private->thread_db;
if (thread_db)
{
+ struct thread_info *saved_inferior;
+ int pid;
td_err_e (*td_ta_delete_p) (td_thragent_t *);
td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta,
td_thr_events_t *event);
@@ -775,6 +788,12 @@ thread_db_free (struct process_info *proc, int detaching)
td_ta_clear_event_p = &td_ta_clear_event;
#endif
+ pid = pid_of (proc);
+ saved_inferior = current_inferior;
+ current_inferior =
+ (struct thread_info *) find_inferior (&all_threads,
+ any_thread_of, &pid);
+
if (detaching && td_ta_clear_event_p != NULL)
{
td_thr_events_t events;
@@ -794,6 +813,7 @@ thread_db_free (struct process_info *proc, int detaching)
free (thread_db);
proc->private->thread_db = NULL;
+ current_inferior = saved_inferior;
}
}