aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/remote.c80
2 files changed, 82 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index af0d7e6..2804269 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2013-01-25 Pedro Alves <palves@redhat.com>
+
+ * remote.c (stop_reply_extract_thread): New.
+ (add_current_inferior_and_thread): New parameter 'wait_status'.
+ Handle it.
+ (remote_start_remote): Pass wait status to
+ add_current_inferior_and_thread.
+ (extended_remote_run): Update comment.
+ (extended_remote_create_inferior_1): Pass wait status to
+ add_current_inferior_and_thread.
+
2013-01-25 Andrew Burgess <aburgess@broadcom.com>
Ulrich Weigand <uweigand@de.ibm.com>
diff --git a/gdb/remote.c b/gdb/remote.c
index 7ea9597..18fe61d 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -3224,22 +3224,77 @@ send_interrupt_sequence (void)
interrupt_sequence_mode);
}
+
+/* If STOP_REPLY is a T stop reply, look for the "thread" register,
+ and extract the PTID. Returns NULL_PTID if not found. */
+
+static ptid_t
+stop_reply_extract_thread (char *stop_reply)
+{
+ if (stop_reply[0] == 'T' && strlen (stop_reply) > 3)
+ {
+ char *p;
+
+ /* Txx r:val ; r:val (...) */
+ p = &stop_reply[3];
+
+ /* Look for "register" named "thread". */
+ while (*p != '\0')
+ {
+ char *p1;
+
+ p1 = strchr (p, ':');
+ if (p1 == NULL)
+ return null_ptid;
+
+ if (strncmp (p, "thread", p1 - p) == 0)
+ return read_ptid (++p1, &p);
+
+ p1 = strchr (p, ';');
+ if (p1 == NULL)
+ return null_ptid;
+ p1++;
+
+ p = p1;
+ }
+ }
+
+ return null_ptid;
+}
+
/* Query the remote target for which is the current thread/process,
add it to our tables, and update INFERIOR_PTID. The caller is
responsible for setting the state such that the remote end is ready
- to return the current thread. */
+ to return the current thread.
+
+ This function is called after handling the '?' or 'vRun' packets,
+ whose response is a stop reply from which we can also try
+ extracting the thread. If the target doesn't support the explicit
+ qC query, we infer the current thread from that stop reply, passed
+ in in WAIT_STATUS, which may be NULL. */
static void
-add_current_inferior_and_thread (void)
+add_current_inferior_and_thread (char *wait_status)
{
struct remote_state *rs = get_remote_state ();
int fake_pid_p = 0;
- ptid_t ptid;
+ ptid_t ptid = null_ptid;
inferior_ptid = null_ptid;
- /* Now, if we have thread information, update inferior_ptid. */
- ptid = remote_current_thread (inferior_ptid);
+ /* Now, if we have thread information, update inferior_ptid. First
+ if we have a stop reply handy, maybe it's a T stop reply with a
+ "thread" register we can extract the current thread from. If
+ not, ask the remote which is the current thread, with qC. The
+ former method avoids a roundtrip. Note we don't use
+ remote_parse_stop_reply as that makes use of the target
+ architecture, which we haven't yet fully determined at this
+ point. */
+ if (wait_status != NULL)
+ ptid = stop_reply_extract_thread (wait_status);
+ if (ptid_equal (ptid, null_ptid))
+ ptid = remote_current_thread (inferior_ptid);
+
if (!ptid_equal (ptid, null_ptid))
{
if (!remote_multi_process_p (rs))
@@ -3400,7 +3455,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
/* Let the stub know that we want it to return the thread. */
set_continue_thread (minus_one_ptid);
- add_current_inferior_and_thread ();
+ add_current_inferior_and_thread (wait_status);
/* init_wait_for_inferior should be called before get_offsets in order
to manage `inserted' flag in bp loc in a correct state.
@@ -7836,7 +7891,7 @@ extended_remote_run (char *args)
if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vRun]) == PACKET_OK)
{
- /* We have a wait response; we don't need it, though. All is well. */
+ /* We have a wait response. All is well. */
return 0;
}
else if (remote_protocol_packets[PACKET_vRun].support == PACKET_DISABLE)
@@ -7863,6 +7918,10 @@ static void
extended_remote_create_inferior_1 (char *exec_file, char *args,
char **env, int from_tty)
{
+ int run_worked;
+ char *stop_reply;
+ struct remote_state *rs = get_remote_state ();
+
/* If running asynchronously, register the target file descriptor
with the event loop. */
if (target_can_async_p ())
@@ -7873,7 +7932,8 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
extended_remote_disable_randomization (disable_randomization);
/* Now restart the remote server. */
- if (extended_remote_run (args) == -1)
+ run_worked = extended_remote_run (args) != -1;
+ if (!run_worked)
{
/* vRun was not supported. Fail if we need it to do what the
user requested. */
@@ -7895,7 +7955,9 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
init_wait_for_inferior ();
}
- add_current_inferior_and_thread ();
+ /* vRun's success return is a stop reply. */
+ stop_reply = run_worked ? rs->buf : NULL;
+ add_current_inferior_and_thread (stop_reply);
/* Get updated offsets, if the stub uses qOffsets. */
get_offsets ();