* remote.c (struct remote_state) <waiting_for_stop_reply>: New

field.
	(remote_open_1): Clear waiting_for_stop_reply.
	(remote_resume): Set waiting_for_stop_reply.
	(remote_wait): Clear or set waiting_for_stop_reply accordingly.
	(putpkt_binary): If we're in async mode and waiting for a stop
	reply, bail out with an error.
	(extended_remote_mourn_1): Clear waiting_for_stop_reply.
This commit is contained in:
Pedro Alves 2008-10-08 19:16:31 +00:00
parent 06d61999fb
commit e24a49d86d
2 changed files with 56 additions and 0 deletions

View File

@ -1,3 +1,14 @@
2008-10-08 Pedro Alves <pedro@codesourcery.com>
* remote.c (struct remote_state) <waiting_for_stop_reply>: New
field.
(remote_open_1): Clear waiting_for_stop_reply.
(remote_resume): Set waiting_for_stop_reply.
(remote_wait): Clear or set waiting_for_stop_reply accordingly.
(putpkt_binary): If we're in async mode and waiting for a stop
reply, bail out with an error.
(extended_remote_mourn_1): Clear waiting_for_stop_reply.
2008-10-08 Pedro Alves <pedro@codesourcery.com>
* remote.c (remote_get_thread_info): If the remote doesn't support

View File

@ -263,6 +263,14 @@ struct remote_state
/* True if the stub reported support for multi-process
extensions. */
int multi_process_aware;
/* True if we resumed the target and we're waiting for the target to
stop. In the mean time, we can't start another command/query.
The remote server wouldn't be ready to process it, so we'd
timeout waiting for a reply that would never come and eventually
we'd close the connection. This can happen in asynchronous mode
because we allow GDB commands while the target is running. */
int waiting_for_stop_reply;
};
/* Returns true if the multi-process extensions are in effect. */
@ -2866,6 +2874,7 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
rs->noack_mode = 0;
rs->multi_process_aware = 0;
rs->extended = extended_p;
rs->waiting_for_stop_reply = 0;
general_thread = not_sent_ptid;
continue_thread = not_sent_ptid;
@ -3411,6 +3420,12 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
NOT asynchronously. */
if (target_can_async_p ())
target_async (inferior_event_handler, 0);
/* We've just told the target to resume. The remote server will
wait for the inferior to stop, and then send a stop reply. In
the mean time, we can't start another command/query ourselves
because the stub wouldn't be ready to process it. */
rs->waiting_for_stop_reply = 1;
}
@ -3649,6 +3664,9 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
remote_stopped_by_watchpoint_p = 0;
/* We got something. */
rs->waiting_for_stop_reply = 0;
switch (buf[0])
{
case 'E': /* Error of some sort. */
@ -3660,6 +3678,10 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
goto got_status;
case 'F': /* File-I/O request. */
remote_fileio_request (buf);
/* This stop reply is special. We reply back to the stub,
and keep waiting for the target to stop. */
rs->waiting_for_stop_reply = 1;
continue;
case 'T': /* Status with PC, SP, FP, ... */
{
@ -3828,6 +3850,10 @@ Packet: '%s'\n"),
}
case 'O': /* Console output. */
remote_console_output (buf + 1);
/* The target didn't really stop; keep waiting. */
rs->waiting_for_stop_reply = 1;
if (target_can_async_p ())
{
/* Return immediately to the event loop. The event loop
@ -3851,11 +3877,17 @@ Packet: '%s'\n"),
strcpy ((char *) buf, last_sent_step ? "s" : "c");
putpkt ((char *) buf);
/* We just told the target to resume, so a stop reply is
in order. */
rs->waiting_for_stop_reply = 1;
continue;
}
/* else fallthrough */
default:
warning (_("Invalid remote reply: %s"), buf);
/* Keep waiting. */
rs->waiting_for_stop_reply = 1;
continue;
}
}
@ -4968,6 +5000,15 @@ putpkt_binary (char *buf, int cnt)
int tcount = 0;
char *p;
/* Catch cases like trying to read memory or listing threads while
we're waiting for a stop reply. The remote server wouldn't be
ready to handle this request, so we'd hang and timeout. We don't
have to worry about this in synchronous mode, because in that
case it's not possible to issue a command while the target is
running. */
if (target_can_async_p () && rs->waiting_for_stop_reply)
error (_("Cannot execute this command while the target is running."));
/* We're sending out a new packet. Make sure we don't look at a
stale cached response. */
rs->cached_wait_status = 0;
@ -5480,6 +5521,10 @@ extended_remote_mourn_1 (struct target_ops *target)
{
struct remote_state *rs = get_remote_state ();
/* In case we got here due to an error, but we're going to stay
connected. */
rs->waiting_for_stop_reply = 0;
/* Unlike "target remote", we do not want to unpush the target; then
the next time the user says "run", we won't be connected. */