aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2008-10-09 18:45:44 +0000
committerPedro Alves <palves@redhat.com>2008-10-09 18:45:44 +0000
commitc8e38a496bffe56c5a8dc92ffe47b67396eac355 (patch)
tree4c09d09e4c8d3971b3ec09cec9cffd4faed817e9 /gdb/remote.c
parentccf8a69b9c64695ae672edced051eac85a53cf35 (diff)
downloadgdb-c8e38a496bffe56c5a8dc92ffe47b67396eac355.zip
gdb-c8e38a496bffe56c5a8dc92ffe47b67396eac355.tar.gz
gdb-c8e38a496bffe56c5a8dc92ffe47b67396eac355.tar.bz2
* remote.c (remote_wait): Rename to...
(remote_wait_as): ... this. Don't loop here. If the remote didn't stop, return TARGET_WAITKIND_IGNORE. (remote_wait): New, reimplemented on top of remote_wait_as.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c454
1 files changed, 232 insertions, 222 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index aa754d2..473dc8e 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -3627,278 +3627,270 @@ remote_console_output (char *msg)
storing status in STATUS just as `wait' would. */
static ptid_t
-remote_wait (ptid_t ptid, struct target_waitstatus *status)
+remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
ptid_t event_ptid = null_ptid;
ULONGEST addr;
int solibs_changed = 0;
+ char *buf, *p;
- status->kind = TARGET_WAITKIND_EXITED;
+ status->kind = TARGET_WAITKIND_IGNORE;
status->value.integer = 0;
- while (1)
+ if (rs->cached_wait_status)
+ /* Use the cached wait status, but only once. */
+ rs->cached_wait_status = 0;
+ else
{
- char *buf, *p;
-
- if (rs->cached_wait_status)
- /* Use the cached wait status, but only once. */
- rs->cached_wait_status = 0;
- else
+ if (!target_is_async_p ())
{
- if (!target_is_async_p ())
+ ofunc = signal (SIGINT, remote_interrupt);
+ /* If the user hit C-c before this packet, or between
+ packets, pretend that it was hit right here. */
+ if (quit_flag)
{
- ofunc = signal (SIGINT, remote_interrupt);
- /* If the user hit C-c before this packet, or between packets,
- pretend that it was hit right here. */
- if (quit_flag)
- {
- quit_flag = 0;
- remote_interrupt (SIGINT);
- }
+ quit_flag = 0;
+ remote_interrupt (SIGINT);
}
- /* FIXME: cagney/1999-09-27: If we're in async mode we should
- _never_ wait for ever -> test on target_is_async_p().
- However, before we do that we need to ensure that the caller
- knows how to take the target into/out of async mode. */
- getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
- if (!target_is_async_p ())
- signal (SIGINT, ofunc);
}
+ /* FIXME: cagney/1999-09-27: If we're in async mode we should
+ _never_ wait for ever -> test on target_is_async_p().
+ However, before we do that we need to ensure that the caller
+ knows how to take the target into/out of async mode. */
+ getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
+ if (!target_is_async_p ())
+ signal (SIGINT, ofunc);
+ }
- buf = rs->buf;
+ buf = rs->buf;
- remote_stopped_by_watchpoint_p = 0;
+ remote_stopped_by_watchpoint_p = 0;
- /* We got something. */
- rs->waiting_for_stop_reply = 0;
+ /* We got something. */
+ rs->waiting_for_stop_reply = 0;
- switch (buf[0])
- {
- case 'E': /* Error of some sort. */
- /* We're out of sync with the target now. Did it continue or not?
- Not is more likely, so report a stop. */
- warning (_("Remote failure reply: %s"), buf);
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_0;
- goto got_status;
- case 'F': /* File-I/O request. */
- remote_fileio_request (buf);
+ switch (buf[0])
+ {
+ case 'E': /* Error of some sort. */
+ /* We're out of sync with the target now. Did it continue or
+ not? Not is more likely, so report a stop. */
+ warning (_("Remote failure reply: %s"), buf);
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_0;
+ break;
+ 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, ... */
- {
- gdb_byte regs[MAX_REGISTER_SIZE];
+ /* 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;
+ break;
+ case 'T': /* Status with PC, SP, FP, ... */
+ {
+ gdb_byte regs[MAX_REGISTER_SIZE];
- /* Expedited reply, containing Signal, {regno, reg} repeat. */
- /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
- ss = signal number
- n... = register number
- r... = register contents
- */
- p = &buf[3]; /* after Txx */
+ /* Expedited reply, containing Signal, {regno, reg} repeat. */
+ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
+ ss = signal number
+ n... = register number
+ r... = register contents
+ */
+ p = &buf[3]; /* after Txx */
- while (*p)
- {
- char *p1;
- char *p_temp;
- int fieldsize;
- LONGEST pnum = 0;
+ while (*p)
+ {
+ char *p1;
+ char *p_temp;
+ int fieldsize;
+ LONGEST pnum = 0;
+
+ /* If the packet contains a register number, save it in
+ pnum and set p1 to point to the character following it.
+ Otherwise p1 points to p. */
- /* If the packet contains a register number, save it
- in pnum and set p1 to point to the character
- following it. Otherwise p1 points to p. */
+ /* If this packet is an awatch packet, don't parse the
+ 'a' as a register number. */
- /* If this packet is an awatch packet, don't parse the
- 'a' as a register number. */
+ if (strncmp (p, "awatch", strlen("awatch")) != 0)
+ {
+ /* Read the ``P'' register number. */
+ pnum = strtol (p, &p_temp, 16);
+ p1 = p_temp;
+ }
+ else
+ p1 = p;
- if (strncmp (p, "awatch", strlen("awatch")) != 0)
+ if (p1 == p) /* No register number present here. */
+ {
+ p1 = strchr (p, ':');
+ if (p1 == NULL)
+ error (_("Malformed packet(a) (missing colon): %s\n\
+Packet: '%s'\n"),
+ p, buf);
+ if (strncmp (p, "thread", p1 - p) == 0)
+ event_ptid = read_ptid (++p1, &p);
+ else if ((strncmp (p, "watch", p1 - p) == 0)
+ || (strncmp (p, "rwatch", p1 - p) == 0)
+ || (strncmp (p, "awatch", p1 - p) == 0))
{
- /* Read the ``P'' register number. */
- pnum = strtol (p, &p_temp, 16);
- p1 = p_temp;
+ remote_stopped_by_watchpoint_p = 1;
+ p = unpack_varlen_hex (++p1, &addr);
+ remote_watch_data_address = (CORE_ADDR)addr;
}
- else
- p1 = p;
-
- if (p1 == p) /* No register number present here. */
+ else if (strncmp (p, "library", p1 - p) == 0)
{
- p1 = strchr (p, ':');
- if (p1 == NULL)
- error (_("Malformed packet(a) (missing colon): %s\n\
-Packet: '%s'\n"),
- p, buf);
- if (strncmp (p, "thread", p1 - p) == 0)
- event_ptid = read_ptid (++p1, &p);
- else if ((strncmp (p, "watch", p1 - p) == 0)
- || (strncmp (p, "rwatch", p1 - p) == 0)
- || (strncmp (p, "awatch", p1 - p) == 0))
- {
- remote_stopped_by_watchpoint_p = 1;
- p = unpack_varlen_hex (++p1, &addr);
- remote_watch_data_address = (CORE_ADDR)addr;
- }
- else if (strncmp (p, "library", p1 - p) == 0)
- {
- p1++;
- p_temp = p1;
- while (*p_temp && *p_temp != ';')
- p_temp++;
-
- solibs_changed = 1;
- p = p_temp;
- }
- else
- {
- /* Silently skip unknown optional info. */
- p_temp = strchr (p1 + 1, ';');
- if (p_temp)
- p = p_temp;
- }
+ p1++;
+ p_temp = p1;
+ while (*p_temp && *p_temp != ';')
+ p_temp++;
+
+ solibs_changed = 1;
+ p = p_temp;
}
else
{
- struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
- p = p1;
+ /* Silently skip unknown optional info. */
+ p_temp = strchr (p1 + 1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
+ }
+ else
+ {
+ struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
+ p = p1;
- if (*p != ':')
- error (_("Malformed packet(b) (missing colon): %s\n\
+ if (*p != ':')
+ error (_("Malformed packet(b) (missing colon): %s\n\
Packet: '%s'\n"),
- p, buf);
- ++p;
+ p, buf);
+ ++p;
- if (reg == NULL)
- error (_("Remote sent bad register number %s: %s\n\
+ if (reg == NULL)
+ error (_("Remote sent bad register number %s: %s\n\
Packet: '%s'\n"),
- phex_nz (pnum, 0), p, buf);
-
- fieldsize = hex2bin (p, regs,
- register_size (target_gdbarch,
- reg->regnum));
- p += 2 * fieldsize;
- if (fieldsize < register_size (target_gdbarch,
- reg->regnum))
- warning (_("Remote reply is too short: %s"), buf);
- regcache_raw_supply (get_current_regcache (),
- reg->regnum, regs);
- }
-
- if (*p != ';')
- error (_("Remote register badly formatted: %s\nhere: %s"),
- buf, p);
- ++p;
+ phex_nz (pnum, 0), p, buf);
+
+ fieldsize = hex2bin (p, regs,
+ register_size (target_gdbarch,
+ reg->regnum));
+ p += 2 * fieldsize;
+ if (fieldsize < register_size (target_gdbarch,
+ reg->regnum))
+ warning (_("Remote reply is too short: %s"), buf);
+ regcache_raw_supply (get_current_regcache (),
+ reg->regnum, regs);
}
+
+ if (*p != ';')
+ error (_("Remote register badly formatted: %s\nhere: %s"),
+ buf, p);
+ ++p;
}
- /* fall through */
- case 'S': /* Old style status, just signal only. */
- if (solibs_changed)
- status->kind = TARGET_WAITKIND_LOADED;
- else
- {
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
- }
- goto got_status;
- case 'W': /* Target exited. */
- case 'X':
- {
- char *p;
- int pid;
- ULONGEST value;
+ }
+ /* fall through */
+ case 'S': /* Old style status, just signal only. */
+ if (solibs_changed)
+ status->kind = TARGET_WAITKIND_LOADED;
+ else
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ }
+ break;
+ case 'W': /* Target exited. */
+ case 'X':
+ {
+ char *p;
+ int pid;
+ ULONGEST value;
- /* GDB used to accept only 2 hex chars here. Stubs should
- only send more if they detect GDB supports
- multi-process support. */
- p = unpack_varlen_hex (&buf[1], &value);
+ /* GDB used to accept only 2 hex chars here. Stubs should
+ only send more if they detect GDB supports multi-process
+ support. */
+ p = unpack_varlen_hex (&buf[1], &value);
- if (buf[0] == 'W')
- {
- /* The remote process exited. */
- status->kind = TARGET_WAITKIND_EXITED;
- status->value.integer = value;
- }
- else
- {
- /* The remote process exited with a signal. */
- status->kind = TARGET_WAITKIND_SIGNALLED;
- status->value.sig = (enum target_signal) value;
- }
+ if (buf[0] == 'W')
+ {
+ /* The remote process exited. */
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = value;
+ }
+ else
+ {
+ /* The remote process exited with a signal. */
+ status->kind = TARGET_WAITKIND_SIGNALLED;
+ status->value.sig = (enum target_signal) value;
+ }
- /* If no process is specified, assume inferior_ptid. */
- pid = ptid_get_pid (inferior_ptid);
- if (*p == '\0')
+ /* If no process is specified, assume inferior_ptid. */
+ pid = ptid_get_pid (inferior_ptid);
+ if (*p == '\0')
+ ;
+ else if (*p == ';')
+ {
+ p++;
+
+ if (p == '\0')
;
- else if (*p == ';')
+ else if (strncmp (p,
+ "process:", sizeof ("process:") - 1) == 0)
{
- p++;
-
- if (p == '\0')
- ;
- else if (strncmp (p,
- "process:", sizeof ("process:") - 1) == 0)
- {
- ULONGEST upid;
- p += sizeof ("process:") - 1;
- unpack_varlen_hex (p, &upid);
- pid = upid;
- }
- else
- error (_("unknown stop reply packet: %s"), buf);
+ ULONGEST upid;
+ p += sizeof ("process:") - 1;
+ unpack_varlen_hex (p, &upid);
+ pid = upid;
}
else
error (_("unknown stop reply packet: %s"), buf);
- event_ptid = ptid_build (pid, 0, 0);
- goto got_status;
}
- case 'O': /* Console output. */
- remote_console_output (buf + 1);
+ else
+ error (_("unknown stop reply packet: %s"), buf);
+ event_ptid = pid_to_ptid (pid);
+ break;
+ }
+ case 'O': /* Console output. */
+ remote_console_output (buf + 1);
- /* The target didn't really stop; keep waiting. */
- rs->waiting_for_stop_reply = 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
- will still be waiting on the inferior afterwards. */
- status->kind = TARGET_WAITKIND_IGNORE;
- goto got_status;
- }
- else
- continue;
- case '\0':
- if (last_sent_signal != TARGET_SIGNAL_0)
- {
- /* Zero length reply means that we tried 'S' or 'C' and
- the remote system doesn't support it. */
- target_terminal_ours_for_output ();
- printf_filtered
- ("Can't send signals to this remote system. %s not sent.\n",
- target_signal_to_name (last_sent_signal));
- last_sent_signal = TARGET_SIGNAL_0;
- target_terminal_inferior ();
-
- 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. */
+ break;
+ case '\0':
+ if (last_sent_signal != TARGET_SIGNAL_0)
+ {
+ /* Zero length reply means that we tried 'S' or 'C' and the
+ remote system doesn't support it. */
+ target_terminal_ours_for_output ();
+ printf_filtered
+ ("Can't send signals to this remote system. %s not sent.\n",
+ target_signal_to_name (last_sent_signal));
+ last_sent_signal = TARGET_SIGNAL_0;
+ target_terminal_inferior ();
+
+ 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;
+ break;
}
+ /* else fallthrough */
+ default:
+ warning (_("Invalid remote reply: %s"), buf);
+ /* Keep waiting. */
+ rs->waiting_for_stop_reply = 1;
+ break;
}
-got_status:
+
+ /* Nothing interesting happened. */
+ if (status->kind == TARGET_WAITKIND_IGNORE)
+ return minus_one_ptid;
+
if (status->kind == TARGET_WAITKIND_EXITED
|| status->kind == TARGET_WAITKIND_SIGNALLED)
{
@@ -3916,6 +3908,24 @@ got_status:
return event_ptid;
}
+static ptid_t
+remote_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ ptid_t event_ptid;
+
+ /* In synchronous mode, keep waiting until the target stops. In
+ asynchronous mode, always return to the event loop. */
+
+ do
+ {
+ event_ptid = remote_wait_as (ptid, status);
+ }
+ while (status->kind == TARGET_WAITKIND_IGNORE
+ && !target_can_async_p ());
+
+ return event_ptid;
+}
+
/* Fetch a single register using a 'p' packet. */
static int