aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog39
-rw-r--r--gdb/maint.c16
-rw-r--r--gdb/remote-mips.c37
-rw-r--r--gdb/remote-nrom.c181
-rw-r--r--gdb/ser-tcp.c44
-rw-r--r--gdb/serial.c50
-rw-r--r--gdb/serial.h5
-rw-r--r--gdb/sparcl-tdep.c2
8 files changed, 253 insertions, 121 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 26b91f1..82a66a8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,42 @@
+Thu Jun 8 15:06:00 1995 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h maint.c monitor.c remote-mips.c remote.c: Add support
+ for `watchdog' variable. This allows the user to put an upper
+ limit on the amount of time that GDB will wait for the target to
+ return from a step or continue operation. This will primarily be
+ used for the testsuite, where it is difficult to come up with a
+ reasonable timeout for things like function calls, which can take
+ as long as three minutes under some circumstances. If the
+ watchdog timer expires, GDB will generate an error that looks like
+ `Watchdog has expired.', and will detach from the target.
+
+ * remote-mips.c (mips_open): Setup initial frame from target.
+ Print it out so that user is told where the program is stopped
+ when they attach.
+
+ * remote-nrom.c: Loads of cleanups. Use serial code to open
+ network connections. Use expect() to wait for response to
+ download command.
+
+ * ser-tcp.c (tcp_open): Retry connection if we get ECONNREFUSED.
+
+ * serial.c serial.h (serial_open serial_fdopen serial_close):
+ Allow users to open the same device multiple times. They all get
+ to share the same serial_t. This is about the only way to have
+ multiple active targets use the same device (for download and
+ debug).
+
+ * sparcl-tdep.c: Keep #include <unistd.h> away from GO32.
+
+ * target.c: Add `targetdebug' variable. If this is non-zero,
+ then a special target is put at the top of the target stack which
+ will cause all calls through the target vector to have their args
+ and results printed out.
+
+Wed Jun 7 17:40:37 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * ch-exp.y: Handle <primitive_value> "->" <modename>.
+
Wed Jun 7 17:46:33 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* mem-break.c (LITTLE_BREAKPOINT): If BREAKPOINT and
diff --git a/gdb/maint.c b/gdb/maint.c
index 479ee6b..7f822ec 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -43,6 +43,14 @@ static void maintenance_time_display PARAMS ((char *, int));
static void maintenance_space_display PARAMS ((char *, int));
+/* Set this to the maximum number of seconds to wait instead of waiting forever
+ in target_wait(). If this timer times out, then it generates an error and
+ the command is aborted. This replaces most of the need for timeouts in the
+ GDB test suite, and makes it possible to distinguish between a hung target
+ and one with slow communications. */
+
+int watchdog = 0;
+
/*
LOCAL FUNCTION
@@ -330,5 +338,13 @@ If a SOURCE file is specified, dump only that file's partial symbols.",
add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
"Check consistency of psymtabs and symtabs.",
&maintenancelist);
+
+ add_show_from_set (
+ add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *)&watchdog,
+ "Set watchdog timer.\n\
+When non-zero, this timeout is used instead of waiting forever for a target to\n\
+finish a low-level step or continue operation. If the specified amount of time\n\
+passes without a response from the target, an error occurs.", &setlist),
+ &showlist);
#endif /* MAINTENANCE_CMDS */
}
diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c
index 170a6ba..6195dbb 100644
--- a/gdb/remote-mips.c
+++ b/gdb/remote-mips.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for MIPS remote debugging protocol.
- Copyright 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Ian Lance Taylor
<ian@cygnus.com>.
@@ -128,7 +128,7 @@ extern struct target_ops mips_ops;
The value is
0x40 + seq
An acknowlegment packet contains the sequence number of the
- packet being acknowledged plus 1 module 64. Data packets are
+ packet being acknowledged plus 1 modulo 64. Data packets are
transmitted in sequence. There may only be one outstanding
unacknowledged data packet at a time. The sequence numbers
are independent in each direction. If an acknowledgement for
@@ -334,10 +334,24 @@ mips_readchar (timeout)
int ch;
static int state = 0;
static char nextstate[5] = { '<', 'I', 'D', 'T', '>' };
+#ifdef MAINTENANCE_CMDS
+ int i;
+
+ i = timeout;
+ if (i == -1 && watchdog > 0)
+ i = watchdog;
+#endif
if (state == 5)
timeout = 1;
ch = SERIAL_READCHAR (mips_desc, timeout);
+#ifdef MAINTENANCE_CMDS
+ if (ch == SERIAL_TIMEOUT && timeout == -1) /* Watchdog went off */
+ {
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.\n");
+ }
+#endif
if (ch == SERIAL_EOF)
mips_error ("End of file from remote");
if (ch == SERIAL_ERROR)
@@ -373,7 +387,10 @@ mips_readchar (timeout)
state = 0;
- mips_error ("Remote board reset");
+ /* At this point, about the only thing we can do is abort the command
+ in progress and get back to command level as quickly as possible. */
+
+ error ("Remote board reset, debug protocol re-initialized.");
}
if (ch == nextstate[state])
@@ -874,7 +891,7 @@ mips_request (cmd, addr, data, perr, timeout)
char rcmd;
int rerrflg;
int rresponse;
-
+
if (cmd != '\0')
{
if (mips_need_reply)
@@ -1031,6 +1048,18 @@ device is attached to the target board (e.g., /dev/ttya).");
ptype = mips_read_processor_type ();
if (ptype)
mips_set_processor_type_command (strsave (ptype), 0);
+
+/* This is really the job of start_remote however, that makes an assumption
+ that the target is about to print out a status message of some sort. That
+ doesn't happen here (in fact, it may not be possible to get the monitor to
+ send the appropriate packet). */
+
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ set_current_frame (create_new_frame (read_fp (), stop_pc));
+ select_frame (get_current_frame (), 0);
+ print_stack_frame (selected_frame, -1, 1);
}
/* Close a connection to the remote board. */
diff --git a/gdb/remote-nrom.c b/gdb/remote-nrom.c
index 1699d4c..0a0a959 100644
--- a/gdb/remote-nrom.c
+++ b/gdb/remote-nrom.c
@@ -28,6 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "gdbcmd.h"
+#include "serial.h"
+
#include <string.h>
#include "inferior.h"
#include "wait.h"
@@ -229,6 +231,10 @@ static int nrom_load_sock = -1;
static int nrom_targ_sock = -1;
static int nrom_ctrl_sock = -1;
+static serial_t load_desc = NULL;
+static serial_t targ_desc = NULL;
+static serial_t ctrl_desc = NULL;
+
/* For binding to the socket we ned a sockaddr_in structure. */
static struct sockaddr_in nrom_sin;
@@ -256,6 +262,8 @@ static int bufindex = 0;
static char workbuf[NROM_BUF_SIZE];
static char sendbuf[NROM_BUF_SIZE];
+static char nrom_hostname[100];
+
/* Forward data declaration. */
extern struct target_ops nrom_ops;
@@ -404,68 +412,75 @@ mem2hex (mem, buf, count)
return buf;
}
+/* Scan input from the remote system, until STRING is found. If BUF is non-
+ zero, then collect input until we have collected either STRING or BUFLEN-1
+ chars. In either case we terminate BUF with a 0. If input overflows BUF
+ because STRING can't be found, return -1, else return number of chars in BUF
+ (minus the terminating NUL). Note that in the non-overflow case, STRING
+ will be at the end of BUF. */
+
static int
-nrom_control_send (s, nbytes)
- char *s;
- int nbytes;
+expect (string)
+ char *string;
{
- long len;
- char buf[10];
-
- /* clear leading characters */
- /* FIXME: The ioctl uses here seem bogus to me. -sts */
- len = 1;
- while (len > 0)
- {
- if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
- {
- perror ("nrom_control_send ioctl");
- return (-1);
- }
- if (len > 0)
- {
- if (read (nrom_ctrl_sock, buf, 1) < 0)
- {
- perror ("nrom_control_send read");
- return (-1);
- }
- }
- }
+ char *p = string;
+ int c;
- if (remote_debug)
- printf_filtered ("nrom_control_send: sending '%s' (%d bytes) to NetROM\n",
- s, nbytes);
+ immediate_quit = 1;
- if (writen (nrom_ctrl_sock, s, nbytes) < 0)
+ while (1)
{
- perror ("nrom_control_send");
- return (-1);
- }
+ c = SERIAL_READCHAR (ctrl_desc, 5);
- /* clear trailing characters */
- len = 1;
- while (len > 0)
- {
- if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
+ if (c == *p++)
{
- perror ("nrom_control_send ioctl");
- return (-1);
- }
- if (len > 0)
- {
- if (read (nrom_ctrl_sock, buf, 1) < 0)
+ if (*p == '\0')
{
- perror ("nrom_control_send read");
- return (-1);
+ immediate_quit = 0;
+
+ return 0;
}
}
+ else
+ {
+ fputc_unfiltered (c, gdb_stdout);
+ p = string;
+ if (c == *p)
+ p++;
+ }
}
+}
+
+static int
+nrom_control_send (s, nbytes)
+ char *s;
+ int nbytes;
+{
+ SERIAL_WRITE (ctrl_desc, s, nbytes);
+
return 0;
}
static void
nrom_kill ()
{
+ nrom_close (0);
+}
+
+static serial_t
+open_socket (name, port)
+ char *name;
+ int port;
+{
+ char sockname[100];
+ serial_t desc;
+
+ sprintf (sockname, "%s:%d", name, port);
+ desc = SERIAL_OPEN (sockname);
+ if (!desc)
+ perror_with_name (sockname);
+
+ return desc;
}
/* Download a file specified in ARGS to the netROM. */
@@ -485,20 +500,9 @@ nrom_load (args, fromtty)
if (nrom_control_send (downloadstring, strlen (downloadstring)) < 0)
error ("nrom_load: control_send() of `%s' failed", downloadstring);
- /* Wait for the download daemon to start up. */
- sleep (1);
-
- nrom_load_sock = socket (AF_INET, SOCK_STREAM, 0);
- if (nrom_load_sock == -1)
- error ("Could not create download socket, error %d", errno);
-
- memset (&sin, 0, sizeof(struct sockaddr_in));
- sin.sin_family = AF_INET;
- sin.sin_port = htons (load_port);
- sin.sin_addr.s_addr = htonl (nrom_ipaddr);
+ expect ("Waiting for a connection...\n");
- if (connect (nrom_load_sock, &sin, sizeof(sin)) == -1)
- error ("Connect failed, error %d", errno);
+ load_desc = open_socket (nrom_hostname, load_port);
pbfd = bfd_openr (args, 0);
@@ -540,7 +544,7 @@ nrom_load (args, fromtty)
bfd_get_section_contents (pbfd, section, buffer, fptr,
count);
- writen (nrom_load_sock, buffer, count);
+ SERIAL_WRITE (load_desc, buffer, count);
section_address += count;
fptr += count;
section_size -= count;
@@ -557,7 +561,8 @@ nrom_load (args, fromtty)
else
error ("\"%s\": Could not open", args);
- close (nrom_load_sock);
+ SERIAL_CLOSE (load_desc);
+ load_desc = NULL;
}
/* This is called not only when we first attach, but also when the
@@ -580,52 +585,24 @@ nrom_open (name, from_tty)
{
int errn;
- if (name)
- nrom_set_ipaddr (name, from_tty);
- else if (nrom_ipaddr == 0)
+ if (!name || strchr (name, '/') || strchr (name, ':'))
error (
"To open a NetROM connection, you must specify the hostname\n\
or IP address of the NetROM device you wish to use.");
- push_target (&nrom_ops);
-
- /* Create the socket used for talking with the target. */
- nrom_targ_sock = socket (AF_INET, SOCK_STREAM, 0);
-
- /* Bind the socket. */
- nrom_sin.sin_family = AF_INET;
- nrom_sin.sin_port = htons (target_port);
- nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
+ strcpy (nrom_hostname, name);
- /* Connect to the remote host. */
- if (connect (nrom_targ_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
- error ("Connect failed, error %d", errno);
+ target_preopen (from_tty);
- /* Create the socket used for talking with the debugger services. */
- nrom_ctrl_sock = socket (AF_INET, SOCK_STREAM, 0);
+ unpush_target (&nrom_ops);
- /* Bind the socket. */
- nrom_sin.sin_family = AF_INET;
- nrom_sin.sin_port = htons (control_port);
- nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
+ targ_desc = open_socket (nrom_hostname, target_port);
+ ctrl_desc = open_socket (nrom_hostname, control_port);
- /* Connect to the remote host. */
- if (connect (nrom_ctrl_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
- {
- errn = errno;
- close (nrom_targ_sock);
- error ("Connect control_socket failed, error %d", errn);
- }
+ push_target (&nrom_ops);
if (from_tty)
- {
- unsigned char *i;
-
- printf_filtered ("Connected to NetROM device \"%s\"", name);
- i = (unsigned char *) &nrom_ipaddr;
- printf_filtered (" (%d.%d.%d.%d)\n",
- UC(i[0]), UC(i[1]), UC(i[2]), UC(i[3]));
- }
+ printf_filtered ("Connected to NetROM device \"%s\"\n", nrom_hostname);
}
static int
@@ -640,6 +617,16 @@ static void
nrom_close (quitting)
int quitting;
{
+ if (load_desc)
+ SERIAL_CLOSE (load_desc);
+ if (targ_desc)
+ SERIAL_CLOSE (targ_desc);
+ if (ctrl_desc)
+ SERIAL_CLOSE (ctrl_desc);
+
+ load_desc = NULL;
+ targ_desc = NULL;
+ ctrl_desc = NULL;
}
/* Attach to the target that is already loaded and possibly running */
@@ -1312,7 +1299,7 @@ struct target_ops nrom_ops = {
nrom_can_run,
0, /* to_notice_signals */
0,
- process_stratum, /* to_stratum */
+ download_stratum, /* to_stratum */
NULL, /* to_next */
1,
1,
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index 029a625..288ccb7 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -79,28 +79,38 @@ tcp_open(scb, name)
return -1;
}
- scb->fd = socket (PF_INET, SOCK_STREAM, 0);
- if (scb->fd < 0)
- return -1;
+ for (i = 1; i <= 15; i++)
+ {
+ scb->fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (scb->fd < 0)
+ return -1;
- /* Allow rapid reuse of this port. */
- tmp = 1;
- setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
+ /* Allow rapid reuse of this port. */
+ tmp = 1;
+ setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
- /* Enable TCP keep alive process. */
- tmp = 1;
- setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
+ /* Enable TCP keep alive process. */
+ tmp = 1;
+ setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
- sockaddr.sin_family = PF_INET;
- sockaddr.sin_port = htons(port);
- memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
- sizeof (struct in_addr));
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons(port);
+ memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
+ sizeof (struct in_addr));
- if (connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr)))
- {
- close(scb->fd);
+ if (!connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr)))
+ break;
+
+ close (scb->fd);
scb->fd = -1;
- return -1;
+
+/* We retry for ECONNREFUSED because that is often a temporary condition, which
+ happens when the server is being restarted. */
+
+ if (errno != ECONNREFUSED)
+ return -1;
+
+ sleep (1);
}
protoent = getprotobyname ("tcp");
diff --git a/gdb/serial.c b/gdb/serial.c
index 631f0f3..291ff3d 100644
--- a/gdb/serial.c
+++ b/gdb/serial.c
@@ -58,6 +58,13 @@ serial_open (name)
serial_t scb;
struct serial_ops *ops;
+ for (scb = scb_base; scb; scb = scb->next)
+ if (scb->name && strcmp (scb->name, name) == 0)
+ {
+ scb->refcnt++;
+ return scb;
+ }
+
if (strcmp (name, "pc") == 0)
ops = serial_interface_lookup ("pc");
else if (strchr (name, ':'))
@@ -81,18 +88,30 @@ serial_open (name)
return NULL;
}
+ scb->name = strsave (name);
+ scb->next = scb_base;
+ scb->refcnt = 1;
+ scb_base = scb;
+
last_serial_opened = scb;
return scb;
}
serial_t
-serial_fdopen(fd)
+serial_fdopen (fd)
const int fd;
{
serial_t scb;
struct serial_ops *ops;
+ for (scb = scb_base; scb; scb = scb->next)
+ if (scb->fd == fd)
+ {
+ scb->refcnt++;
+ return scb;
+ }
+
ops = serial_interface_lookup ("hardwire");
if (!ops)
@@ -107,6 +126,11 @@ serial_fdopen(fd)
scb->fd = fd;
+ scb->name = NULL;
+ scb->next = scb_base;
+ scb->refcnt = 1;
+ scb_base = scb;
+
last_serial_opened = scb;
return scb;
@@ -116,6 +140,8 @@ void
serial_close(scb)
serial_t scb;
{
+ serial_t tmp_scb;
+
last_serial_opened = NULL;
/* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
@@ -124,7 +150,27 @@ serial_close(scb)
if (!scb)
return;
- scb->ops->close(scb);
+ scb->refcnt--;
+ if (scb->refcnt > 0)
+ return;
+
+ scb->ops->close (scb);
+
+ if (scb->name)
+ free (scb->name);
+
+ if (scb_base == scb)
+ scb_base = scb_base->next;
+ else
+ for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
+ {
+ if (tmp_scb->next != scb)
+ continue;
+
+ tmp_scb->next = tmp_scb->next->next;
+ break;
+ }
+
free(scb);
}
diff --git a/gdb/serial.h b/gdb/serial.h
index 2dbb1aa..8f4222f 100644
--- a/gdb/serial.h
+++ b/gdb/serial.h
@@ -36,10 +36,15 @@ struct _serial_t
/* ser-unix.c termio{,s} only, we still need to wait for this many more
seconds. */
int timeout_remaining;
+ char *name; /* The name of the device or host */
+ struct _serial_t *next; /* Pointer to the next serial_t */
+ int refcnt; /* Number of pointers to this block */
};
typedef struct _serial_t *serial_t;
+serial_t scb_base; /* Pointer to list of scb's */
+
struct serial_ops {
char *name;
struct serial_ops *next;
diff --git a/gdb/sparcl-tdep.c b/gdb/sparcl-tdep.c
index bf3d87b..89e293c 100644
--- a/gdb/sparcl-tdep.c
+++ b/gdb/sparcl-tdep.c
@@ -24,8 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "serial.h"
#include <sys/types.h>
#include <sys/time.h>
-#include <unistd.h>
#ifndef __GO32__
+#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>