diff options
author | Pedro Alves <palves@redhat.com> | 2008-07-10 22:58:37 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2008-07-10 22:58:37 +0000 |
commit | 4c28f408dfc2ab71b7995f061cc725d3f217ec9c (patch) | |
tree | ef445522d9570d3095191dd7317fddcd48db584d /gdb/linux-thread-db.c | |
parent | 981505ef9aa495c8c67d1c9623c7ad3b586d678b (diff) | |
download | binutils-4c28f408dfc2ab71b7995f061cc725d3f217ec9c.zip binutils-4c28f408dfc2ab71b7995f061cc725d3f217ec9c.tar.gz binutils-4c28f408dfc2ab71b7995f061cc725d3f217ec9c.tar.bz2 |
Non-stop linux native.
* linux-nat.c (linux_test_for_tracefork): Block events while we're
here.
(get_pending_status): Implement non-stop mode.
(linux_nat_detach): Stop threads before detaching.
(linux_nat_resume): In non-stop mode, always resume only a single
PTID.
(linux_handle_extended_wait): On a clone event, in non-stop mode,
add new lwp to GDB's thread table, and mark as running, executing
and stopped appropriately.
(linux_nat_filter_event): Don't assume there are other running
threads when a thread exits.
(linux_nat_wait): Mark the main thread as running and executing.
In non-stop mode, don't stop all lwps.
(linux_nat_kill): Stop lwps before killing them.
(linux_nat_thread_alive): Use signal 0 to detect if a thread is
alive.
(send_sigint_callback): New.
(linux_nat_stop): New.
(linux_nat_add_target): Set to_stop to linux_nat_stop.
* linux-nat.h (thread_db_attach_lwp): Declare.
* linux-thread-db.c (thread_get_info_callback): Check for new
threads if we have none.
(thread_from_lwp, enable_thread_event): Set proc_handle.pid to the
stopped lwp. Check for new threads if we have none.
(thread_db_attach_lwp): New.
(thread_db_init): Set proc_handle.pid to inferior_ptid.
(check_event): Set proc_handle.pid to the stopped lwp.
(thread_db_find_new_threads): Set proc_handle.pid to any stopped
lwp available, bail out if there is none.
* linux-fork.c (linux_fork_killall): Use SIGKILL instead of
PTRACE_KILL.
Diffstat (limited to 'gdb/linux-thread-db.c')
-rw-r--r-- | gdb/linux-thread-db.c | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 7e40e9f..650cbaa 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -283,7 +283,10 @@ thread_get_info_callback (const td_thrhandle_t *thp, void *infop) if (thread_info == NULL) { /* New thread. Attach to it now (why wait?). */ - attach_thread (thread_ptid, thp, &ti); + if (!have_threads ()) + thread_db_find_new_threads (); + else + attach_thread (thread_ptid, thp, &ti); thread_info = find_thread_pid (thread_ptid); gdb_assert (thread_info != NULL); } @@ -308,6 +311,8 @@ thread_from_lwp (ptid_t ptid) LWP. */ gdb_assert (GET_LWP (ptid) != 0); + /* Access an lwp we know is stopped. */ + proc_handle.pid = GET_LWP (ptid); err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); if (err != TD_OK) error (_("Cannot find user-level thread for LWP %ld: %s"), @@ -332,6 +337,48 @@ thread_from_lwp (ptid_t ptid) } +/* Attach to lwp PTID, doing whatever else is required to have this + LWP under the debugger's control --- e.g., enabling event + reporting. Returns true on success. */ +int +thread_db_attach_lwp (ptid_t ptid) +{ + td_thrhandle_t th; + td_thrinfo_t ti; + td_err_e err; + + if (!using_thread_db) + return 0; + + /* This ptid comes from linux-nat.c, which should always fill in the + LWP. */ + gdb_assert (GET_LWP (ptid) != 0); + + /* Access an lwp we know is stopped. */ + proc_handle.pid = GET_LWP (ptid); + + /* If we have only looked at the first thread before libpthread was + initialized, we may not know its thread ID yet. Make sure we do + before we add another thread to the list. */ + if (!have_threads ()) + thread_db_find_new_threads (); + + err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); + if (err != TD_OK) + /* Cannot find user-level thread. */ + return 0; + + err = td_thr_get_info_p (&th, &ti); + if (err != TD_OK) + { + warning (_("Cannot get thread info: %s"), thread_db_err_str (err)); + return 0; + } + + attach_thread (ptid, &th, &ti); + return 1; +} + void thread_db_init (struct target_ops *target) { @@ -418,6 +465,9 @@ enable_thread_event (td_thragent_t *thread_agent, int event, CORE_ADDR *bp) td_notify_t notify; td_err_e err; + /* Access an lwp we know is stopped. */ + proc_handle.pid = GET_LWP (inferior_ptid); + /* Get the breakpoint address for thread EVENT. */ err = td_ta_event_addr_p (thread_agent, event, ¬ify); if (err != TD_OK) @@ -761,6 +811,15 @@ check_event (ptid_t ptid) if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr) return; + /* Access an lwp we know is stopped. */ + proc_handle.pid = GET_LWP (ptid); + + /* If we have only looked at the first thread before libpthread was + initialized, we may not know its thread ID yet. Make sure we do + before we add another thread to the list. */ + if (!have_threads ()) + thread_db_find_new_threads (); + /* If we are at a create breakpoint, we do not know what new lwp was created and cannot specifically locate the event message for it. We have to call td_ta_event_getmsg() to get @@ -951,11 +1010,27 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) return 0; } +/* Search for new threads, accessing memory through stopped thread + PTID. */ + static void thread_db_find_new_threads (void) { td_err_e err; + struct lwp_info *lp; + ptid_t ptid; + + /* In linux, we can only read memory through a stopped lwp. */ + ALL_LWPS (lp, ptid) + if (lp->stopped) + break; + + if (!lp) + /* There is no stopped thread. Bail out. */ + return; + /* Access an lwp we know is stopped. */ + proc_handle.pid = GET_LWP (ptid); /* Iterate over all user-space threads to discover new threads. */ err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, |