From 1941c569e4194f66d980d62eb3ab534d8011c3ce Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 4 Mar 2009 22:50:59 +0000 Subject: [PATCH] * inferior.h (notice_new_inferior): Declare. * infcmd.c (notice_new_inferior): New. * remote.c (remote_add_inferior, remote_add_thread): New. (notice_new_inferiors): Rename to... (remote_notice_new_inferior): ... this. Add RUNNING argument. Use remote_add_thread instead of add_thread, passing it the RUNNING argument. Add an inferior with remote_add_inferior. If we just learned about an inferior, call notice_new_inferior. (record_currthread): Adjust. (remote_threads_info): Adjust to use remote_notice_new_inferior. (remote_start_remote, extended_remote_attach_1): Use remote_add_inferior. (process_stop_reply): Adjust. Call remote_notice_new_inferior after handling expedited registers and watchpoint state. (extended_remote_create_inferior_1): Use remote_add_inferior. --- gdb/ChangeLog | 17 +++++++++ gdb/infcmd.c | 66 ++++++++++++++++++++++++++++++++ gdb/inferior.h | 2 + gdb/remote.c | 100 +++++++++++++++++++++++++++++++++---------------- 4 files changed, 152 insertions(+), 33 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2bf365da5c2..f260965c59b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2009-03-04 Pedro Alves + + * inferior.h (notice_new_inferior): Declare. + * infcmd.c (notice_new_inferior): New. + * remote.c (remote_add_inferior, remote_add_thread): New. + (notice_new_inferiors): Rename to... + (remote_notice_new_inferior): ... this. Add RUNNING argument. + Use remote_add_thread instead of add_thread, passing it the + RUNNING argument. Add an inferior with remote_add_inferior. If + we just learned about an inferior, call notice_new_inferior. + (record_currthread): Adjust. + (remote_threads_info): Adjust to use remote_notice_new_inferior. + (remote_start_remote, extended_remote_attach_1): Use remote_add_inferior. + (process_stop_reply): Adjust. Call remote_notice_new_inferior + after handling expedited registers and watchpoint state. + (extended_remote_create_inferior_1): Use remote_add_inferior. + 2009-03-04 Aleksandar Ristovski * infcmd.c (registers_info): Remove register number case. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 37a237a12f6..6aed426b7fc 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2313,6 +2313,72 @@ attach_command (char *args, int from_tty) discard_cleanups (back_to); } +/* We had just found out that the target was already attached to an + inferior. PTID points at a thread of this new inferior, that is + the most likely to be stopped right now, but not necessarily so. + The new inferior is assumed to be already added to the inferior + list at this point. If LEAVE_RUNNING, then leave the threads of + this inferior running, except those we've explicitly seen reported + as stopped. */ + +void +notice_new_inferior (ptid_t ptid, int leave_running, int from_tty) +{ + struct cleanup* old_chain; + int async_exec; + + old_chain = make_cleanup (null_cleanup, NULL); + + /* If in non-stop, leave threads as running as they were. If + they're stopped for some reason other than us telling it to, the + target reports a signal != TARGET_SIGNAL_0. We don't try to + resume threads with such a stop signal. */ + async_exec = non_stop; + + if (!ptid_equal (inferior_ptid, null_ptid)) + make_cleanup_restore_current_thread (); + + switch_to_thread (ptid); + + /* When we "notice" a new inferior we need to do all the things we + would normally do if we had just attached to it. */ + + if (is_executing (inferior_ptid)) + { + struct inferior *inferior = current_inferior (); + + /* We're going to install breakpoints, and poke at memory, + ensure that the inferior is stopped for a moment while we do + that. */ + target_stop (inferior_ptid); + + inferior->stop_soon = STOP_QUIETLY_REMOTE; + + /* Wait for stop before proceeding. */ + if (target_can_async_p ()) + { + struct attach_command_continuation_args *a; + + a = xmalloc (sizeof (*a)); + a->args = xstrdup (""); + a->from_tty = from_tty; + a->async_exec = async_exec; + add_inferior_continuation (attach_command_continuation, a, + attach_command_continuation_free_args); + + do_cleanups (old_chain); + return; + } + else + wait_for_inferior (0); + } + + async_exec = leave_running; + attach_command_post_wait ("" /* args */, from_tty, async_exec); + + do_cleanups (old_chain); +} + /* * detach_command -- * takes a program previously attached to and detaches it. diff --git a/gdb/inferior.h b/gdb/inferior.h index c4594112d34..6a1c01acd52 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -281,6 +281,8 @@ extern void interrupt_target_1 (int all_threads); extern void detach_command (char *, int); +extern void notice_new_inferior (ptid_t, int, int); + /* Address at which inferior stopped. */ extern CORE_ADDR stop_pc; diff --git a/gdb/remote.c b/gdb/remote.c index 6efad54bcee..390924f4b54 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1118,9 +1118,53 @@ static ptid_t any_thread_ptid; static ptid_t general_thread; static ptid_t continue_thread; +/* Add PID to GDB's inferior table. Since we can be connected to a + remote system before before knowing about any inferior, mark the + target with execution when we find the first inferior. */ + +static struct inferior * +remote_add_inferior (int pid) +{ + struct remote_state *rs = get_remote_state (); + struct inferior *inf; + + inf = add_inferior (pid); + + /* This may be the first inferior we hear about. */ + if (!target_has_execution) + { + if (rs->extended) + target_mark_running (&extended_remote_ops); + else + target_mark_running (&remote_ops); + } + + return inf; +} + +/* Add thread PTID to GDB's thread list. Tag it as executing/running + according to RUNNING. */ + static void -notice_new_inferiors (ptid_t currthread) +remote_add_thread (ptid_t ptid, int running) { + add_thread (ptid); + + set_executing (ptid, running); + set_running (ptid, running); +} + +/* Come here when we learn about a thread id from the remote target. + It may be the first time we hear about such thread, so take the + opportunity to add it to GDB's thread list. In case this is the + first time we're noticing its corresponding inferior, add it to + GDB's inferior list as well. */ + +static void +remote_notice_new_inferior (ptid_t currthread, int running) +{ + struct remote_state *rs = get_remote_state (); + /* If this is a new thread, add it to GDB's thread list. If we leave it up to WFI to do this, bad things will happen. */ @@ -1128,12 +1172,14 @@ notice_new_inferiors (ptid_t currthread) { /* We're seeing an event on a thread id we knew had exited. This has to be a new thread reusing the old id. Add it. */ - add_thread (currthread); + remote_add_thread (currthread, running); return; } if (!in_thread_list (currthread)) { + struct inferior *inf = NULL; + if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid)) { /* inferior_ptid has no thread member yet. This can happen @@ -1161,10 +1207,16 @@ notice_new_inferiors (ptid_t currthread) may not know about it yet. Add it before adding its child thread, so notifications are emitted in a sensible order. */ if (!in_inferior_list (ptid_get_pid (currthread))) - add_inferior (ptid_get_pid (currthread)); + inf = remote_add_inferior (ptid_get_pid (currthread)); /* This is really a new thread. Add it. */ - add_thread (currthread); + remote_add_thread (currthread, running); + + /* If we found a new inferior, let the common code do whatever + it needs to with it (e.g., read shared libraries, insert + breakpoints). */ + if (inf != NULL) + notice_new_inferior (currthread, running, 0); } } @@ -1183,7 +1235,7 @@ record_currthread (ptid_t currthread) /* We're just invalidating the local thread mirror. */ return; - notice_new_inferiors (currthread); + remote_notice_new_inferior (currthread, 0); } static char *last_pass_packet; @@ -2146,27 +2198,15 @@ remote_threads_info (struct target_ops *ops) do { new_thread = read_ptid (bufp, &bufp); - if (!ptid_equal (new_thread, null_ptid) - && (!in_thread_list (new_thread) - || is_exited (new_thread))) + if (!ptid_equal (new_thread, null_ptid)) { - /* When connected to a multi-process aware stub, - "info threads" may show up threads of - inferiors we didn't know about yet. Add them - now, and before adding any of its child - threads, so notifications are emitted in a - sensible order. */ - if (!in_inferior_list (ptid_get_pid (new_thread))) - add_inferior (ptid_get_pid (new_thread)); - - add_thread (new_thread); - /* In non-stop mode, we assume new found threads - are running until we proven otherwise with a + are running until proven otherwise with a stop reply. In all-stop, we can only get here if all threads are stopped. */ - set_executing (new_thread, non_stop ? 1 : 0); - set_running (new_thread, non_stop ? 1 : 0); + int running = non_stop ? 1 : 0; + + remote_notice_new_inferior (new_thread, running); } } while (*bufp++ == ','); /* comma-separated list */ @@ -2605,9 +2645,6 @@ remote_start_remote (struct ui_out *uiout, void *opaque) } else { - if (args->extended_p) - target_mark_running (args->target); - /* Save the reply for later. */ wait_status = alloca (strlen (rs->buf) + 1); strcpy (wait_status, rs->buf); @@ -2628,7 +2665,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque) /* Now, if we have thread information, update inferior_ptid. */ inferior_ptid = remote_current_thread (inferior_ptid); - add_inferior (ptid_get_pid (inferior_ptid)); + remote_add_inferior (ptid_get_pid (inferior_ptid)); /* Always add the main thread. */ add_thread_silent (inferior_ptid); @@ -3394,13 +3431,12 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty) error (_("Attaching to %s failed"), target_pid_to_str (pid_to_ptid (pid))); - target_mark_running (target); inferior_ptid = pid_to_ptid (pid); /* Now, if we have thread information, update inferior_ptid. */ inferior_ptid = remote_current_thread (inferior_ptid); - inf = add_inferior (pid); + inf = remote_add_inferior (pid); inf->attach_flag = 1; if (non_stop) @@ -4508,8 +4544,6 @@ process_stop_reply (struct stop_reply *stop_reply, if (status->kind != TARGET_WAITKIND_EXITED && status->kind != TARGET_WAITKIND_SIGNALLED) { - notice_new_inferiors (ptid); - /* Expedited registers. */ if (stop_reply->regcache) { @@ -4526,6 +4560,8 @@ process_stop_reply (struct stop_reply *stop_reply, remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p; remote_watch_data_address = stop_reply->watch_data_address; + + remote_notice_new_inferior (ptid, 0); } stop_reply_xfree (stop_reply); @@ -6725,11 +6761,9 @@ extended_remote_create_inferior_1 (char *exec_file, char *args, /* Now, if we have thread information, update inferior_ptid. */ inferior_ptid = remote_current_thread (inferior_ptid); - add_inferior (ptid_get_pid (inferior_ptid)); + remote_add_inferior (ptid_get_pid (inferior_ptid)); add_thread_silent (inferior_ptid); - target_mark_running (&extended_remote_ops); - /* Get updated offsets, if the stub uses qOffsets. */ get_offsets (); } -- 2.30.2