diff options
-rw-r--r-- | gdb/ChangeLog | 39 | ||||
-rw-r--r-- | gdb/maint.c | 16 | ||||
-rw-r--r-- | gdb/remote-mips.c | 37 | ||||
-rw-r--r-- | gdb/remote-nrom.c | 181 | ||||
-rw-r--r-- | gdb/ser-tcp.c | 44 | ||||
-rw-r--r-- | gdb/serial.c | 50 | ||||
-rw-r--r-- | gdb/serial.h | 5 | ||||
-rw-r--r-- | gdb/sparcl-tdep.c | 2 |
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> |