summaryrefslogtreecommitdiff
path: root/gdb/thread-db.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2001-05-06 17:00:44 +0000
committerMark Kettenis <kettenis@gnu.org>2001-05-06 17:00:44 +0000
commitff465ff713c6437003f2d0c592e3140b442a861f (patch)
treed0eea006154a1a1cba7616bb6561f3385e5fa115 /gdb/thread-db.c
parentff63ff77ade277ae9e5ffb1fd3d7d893ba6817ff (diff)
downloadgdb-ff465ff713c6437003f2d0c592e3140b442a861f.tar.gz
Implement attach/detach for multi-threaded programs on Linux.
* thread-db.c (keep_thread_db): Adjust comment. (deactivate_target): Removed. (thread_db_new_objfile): Don't call deactivate_target. Implement guts of deactivate_target inline instead. (attach_thread): Call ATTACH_LWP unconditionally if defined. (thread_db_attach): New function. (thread_db_detach): Don't call deactivate_target. Do necessary cleanup inline instead. Set inferior_ptid to LWP corresponding to the current user-level thread. (thread_db_kill): Set inferior_ptid to LWP corresponding to the current user-level thread. (thread_db_create_inferior): Deactivate target vector if KEEP_THREAD_DB is zero. (thread_db_mourn_inferior): Don't call deactivate_target. Do necessary cleanup inline instead. (init_thread_db_ops): Initialize to_attach field to thread_db_attach. * lin-lwp.c (lin_lwp_mourn_inferior): Remove prototype. (stop_wait_callback): Add prototype. (init_lwp_list): Add comment about when to re-initialize the LWP list. (lin_lwp_attach_lwp): Only call ptrace for cloned processes. Avoid adding publicates to the LWP list. Only mark an LWP as signalled if it doesn't correspond to a cloned process. (lin_lwp_attach): Add initial process to the LWP list. Make sure it's stopped and fake a SIGSTOP. (detach_callback): New function. (lin_lwp_detach): Implement. (lin_lwp_create_inferior): Don't re-initialize LWP list here. Call child_ops.to_create_inferior directly instead of via target_beneath local. (lin_lwp_mourn_inferior): Call child_ops.to_mourn_inferior directly instead of via target_beneath local.
Diffstat (limited to 'gdb/thread-db.c')
-rw-r--r--gdb/thread-db.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/gdb/thread-db.c b/gdb/thread-db.c
index 8c1bdba4411..ab94429bb8e 100644
--- a/gdb/thread-db.c
+++ b/gdb/thread-db.c
@@ -56,7 +56,8 @@ static void (*target_new_objfile_chain) (struct objfile *objfile);
/* Non-zero if we're using this module's target vector. */
static int using_thread_db;
-/* Non-zero if we musn't deactivate this module's target vector. */
+/* Non-zero if we have to keep this module's target vector active
+ across re-runs. */
static int keep_thread_db;
/* Non-zero if we have determined the signals used by the threads
@@ -507,20 +508,6 @@ disable_thread_signals (void)
}
static void
-deactivate_target (void)
-{
- /* Forget about the child's process ID. We shouldn't need it
- anymore. */
- proc_handle.pid = 0;
-
- if (! keep_thread_db)
- {
- using_thread_db = 0;
- unpush_target (&thread_db_ops);
- }
-}
-
-static void
thread_db_new_objfile (struct objfile *objfile)
{
td_err_e err;
@@ -528,11 +515,15 @@ thread_db_new_objfile (struct objfile *objfile)
if (objfile == NULL)
{
/* All symbols have been discarded. If the thread_db target is
- active, deactivate it now, even if the application was linked
- statically against the thread library. */
- keep_thread_db = 0;
+ active, deactivate it now. */
if (using_thread_db)
- deactivate_target ();
+ {
+ gdb_assert (proc_handle.pid == 0);
+ unpush_target (&thread_db_ops);
+ using_thread_db = 0;
+ }
+
+ keep_thread_db = 0;
goto quit;
}
@@ -612,8 +603,7 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
/* Under Linux, we have to attach to each and every thread. */
#ifdef ATTACH_LWP
- if (ti_p->ti_lid != GET_PID (ptid))
- ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
+ ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
#endif
/* Enable thread event reporting for this thread. */
@@ -624,6 +614,23 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
}
static void
+thread_db_attach (char *args, int from_tty)
+{
+ target_beneath->to_attach (args, from_tty);
+
+ /* Destroy thread info; it's no longer valid. */
+ init_thread_list ();
+
+ /* The child process is now the actual multi-threaded
+ program. Snatch its process ID... */
+ proc_handle.pid = GET_PID (inferior_ptid);
+
+ /* ...and perform the remaining initialization steps. */
+ enable_thread_event_reporting ();
+ thread_db_find_new_threads();
+}
+
+static void
detach_thread (ptid_t ptid, int verbose)
{
if (verbose)
@@ -634,7 +641,14 @@ static void
thread_db_detach (char *args, int from_tty)
{
disable_thread_event_reporting ();
- deactivate_target ();
+
+ /* There's no need to save & restore inferior_ptid here, since the
+ inferior is supposed to be survive this function call. */
+ inferior_ptid = lwp_from_thread (inferior_ptid);
+
+ /* Forget about the child's process ID. We shouldn't need it
+ anymore. */
+ proc_handle.pid = 0;
target_beneath->to_detach (args, from_tty);
}
@@ -860,12 +874,21 @@ thread_db_store_registers (int regno)
static void
thread_db_kill (void)
{
+ /* There's no need to save & restore inferior_ptid here, since the
+ inferior isn't supposed to survive this function call. */
+ inferior_ptid = lwp_from_thread (inferior_ptid);
target_beneath->to_kill ();
}
static void
thread_db_create_inferior (char *exec_file, char *allargs, char **env)
{
+ if (! keep_thread_db)
+ {
+ unpush_target (&thread_db_ops);
+ using_thread_db = 0;
+ }
+
target_beneath->to_create_inferior (exec_file, allargs, env);
}
@@ -888,7 +911,10 @@ static void
thread_db_mourn_inferior (void)
{
remove_thread_event_breakpoints ();
- deactivate_target ();
+
+ /* Forget about the child's process ID. We shouldn't need it
+ anymore. */
+ proc_handle.pid = 0;
target_beneath->to_mourn_inferior ();
}
@@ -996,6 +1022,7 @@ init_thread_db_ops (void)
thread_db_ops.to_shortname = "multi-thread";
thread_db_ops.to_longname = "multi-threaded child process.";
thread_db_ops.to_doc = "Threads and pthreads support.";
+ thread_db_ops.to_attach = thread_db_attach;
thread_db_ops.to_detach = thread_db_detach;
thread_db_ops.to_resume = thread_db_resume;
thread_db_ops.to_wait = thread_db_wait;