diff options
author | Mark Kettenis <kettenis@gnu.org> | 2001-05-06 17:00:44 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2001-05-06 17:00:44 +0000 |
commit | c194fbe18b3dc65535031125bdaab04383f892f7 (patch) | |
tree | da822a770f49aca51a3a859c3a90ac500b528b4b /gdb/thread-db.c | |
parent | d8708f403e7d1df1165e12d4141506a804698666 (diff) | |
download | gdb-c194fbe18b3dc65535031125bdaab04383f892f7.zip gdb-c194fbe18b3dc65535031125bdaab04383f892f7.tar.gz gdb-c194fbe18b3dc65535031125bdaab04383f892f7.tar.bz2 |
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.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/gdb/thread-db.c b/gdb/thread-db.c index 8c1bdba..ab94429 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; |