From 41e170e271e1d68418cee0b872d15c68e4450403 Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Sat, 26 Jun 1993 00:41:00 +0000 Subject: [PATCH] * gdbserver/Makefile.in: Add dependancies on server.h. * gdbserver/remote-gutils.c: Remove lots of unused functions and variables. * gdbserver/remote-inflow.c: Remove lots of unused variables and #includes. Also, use PTRACE_* symbols instead of constants. (mywait): Surround calls to wait() with enable/disable_async_io() so that we can be interrupted from GDB while waiting for the child. Also, handle child exit more gracefully. * gdbserver/remote-server.c: Remove lots of unused variables. Move all extern defs into server.h. Redo main loop so that failure from getpkt() causes communications to be re-established. Fix 'k' command so that it restarts the child. * gdbserver/remote-utils.c: Remove lots of unloved vars and subrs. Move many extern decls into server.h. (remote_open): For tcp, seperate usage of proto fd from connected fd. Close proto fd after getting connection. (putpkt/getpkt): Pay attention to errors when reading/writing. Report these to the caller. New routines input_interrupt/enable_async_io/disable_async_io to make it possible to get an I/O interrupt when data arrives from the comm link. * serial.h: New file to contain common defs for all remote files. --- gdb/gdbserver/remote-gutils.c | 332 +--------------------------------- gdb/gdbserver/remote-inflow.c | 59 ++---- gdb/gdbserver/remote-server.c | 153 +++++++--------- 3 files changed, 81 insertions(+), 463 deletions(-) diff --git a/gdb/gdbserver/remote-gutils.c b/gdb/gdbserver/remote-gutils.c index 9db96415b55..de8226b15be 100644 --- a/gdb/gdbserver/remote-gutils.c +++ b/gdb/gdbserver/remote-gutils.c @@ -17,123 +17,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "server.h" #include -#include -#include "defs.h" -#include -void error (); -void fatal (); - -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; - -/* Nonzero means a quit has been requested. */ - -int quit_flag; - -/* Nonzero means quit immediately if Control-C is typed now, - rather than waiting until QUIT is executed. */ - -int immediate_quit; - -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (function, arg) - void (*function) (); - PTR arg; -{ - register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - register struct cleanup *old_chain = cleanup_chain; - - new->next = cleanup_chain; - new->function = function; - new->arg = arg; - cleanup_chain = new; - - return old_chain; -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - (*ptr->function) (ptr->arg); - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* This function is useful for cleanups. - Do - - foo = xmalloc (...); - old_chain = make_cleanup (free_current_contents, &foo); - - to arrange to free the object thus allocated. */ - -void -free_current_contents (location) - char **location; -{ - free (*location); -} - /* Generally useful subroutines used throughout the program. */ -/* Like malloc but get error if no storage available. */ - -PTR -xmalloc (size) - long size; -{ - register char *val = (char *) malloc (size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - -/* Like realloc but get error if no storage available. */ - -PTR -xrealloc (ptr, size) - PTR ptr; - long size; -{ - register char *val = (char *) realloc (ptr, size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - /* Print the system error message for errno, and also mention STRING as the file name for which the error was encountered. Then return to command level. */ @@ -161,51 +49,6 @@ perror_with_name (string) error ("%s.", combined); } -/* Print the system error message for ERRCODE, and also mention STRING - as the file name for which the error was encountered. */ - -void -print_sys_errmsg (string, errcode) - char *string; - int errcode; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - char *err; - char *combined; - - if (errcode < sys_nerr) - err = sys_errlist[errcode]; - else - err = "unknown error"; - - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - printf ("%s.\n", combined); -} - -void -quit () -{ - fflush (stdout); - ioctl (fileno (stdout), TIOCFLUSH, 0); - error ("Quit"); -} - -/* Control C comes here */ - -void -request_quit (ignored) - int ignored; -{ - quit_flag = 1; - if (immediate_quit) - quit (); -} - /* Print an error message and return to command level. STRING is the error message, used as a fprintf string, and ARG is passed as an argument to it. */ @@ -237,176 +80,3 @@ fatal (string, arg) fprintf (stderr, "\n"); exit (1); } - -/* Make a copy of the string at PTR with SIZE characters - (and add a null character at the end in the copy). - Uses malloc to get the space. Returns the address of the copy. */ - -char * -savestring (ptr, size) - const char *ptr; - int size; -{ - register char *p = (char *) xmalloc (size + 1); - bcopy (ptr, p, size); - p[size] = 0; - return p; -} - -void -print_spaces (n, file) - register int n; - register FILE *file; -{ - while (n-- > 0) - fputc (' ', file); -} - -/* Ask user a y-or-n question and return 1 iff answer is yes. - Takes three args which are given to printf to print the question. - The first, a control string, should end in "? ". - It should not say how to answer, because we do that. */ - -int -query (ctlstr, arg1, arg2) - char *ctlstr; -{ - register int answer; - - /* Automatically answer "yes" if input is not from a terminal. */ - /***********if (!input_from_terminal_p ()) - return 1; *************************/ - - while (1) - { - printf (ctlstr, arg1, arg2); - printf ("(y or n) "); - fflush (stdout); - answer = fgetc (stdin); - clearerr (stdin); /* in case of C-d */ - if (answer != '\n') - while (fgetc (stdin) != '\n') - clearerr (stdin); - if (answer >= 'a') - answer -= 040; - if (answer == 'Y') - return 1; - if (answer == 'N') - return 0; - printf ("Please answer y or n.\n"); - } -} - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -int -parse_escape (string_ptr) - char **string_ptr; -{ - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return '\a'; - case 'b': - return '\b'; - case 'e': - return 033; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - if ((c = *(*string_ptr)++) >= '0' && c <= '7') - { - i *= 8; - i += c - '0'; - } - else - { - (*string_ptr)--; - break; - } - } - return i; - } - default: - return c; - } -} - -void -printchar (ch, stream) - unsigned char ch; - FILE *stream; -{ - register int c = ch; - if (c < 040 || c >= 0177) - { - if (c == '\n') - fprintf (stream, "\\n"); - else if (c == '\b') - fprintf (stream, "\\b"); - else if (c == '\t') - fprintf (stream, "\\t"); - else if (c == '\f') - fprintf (stream, "\\f"); - else if (c == '\r') - fprintf (stream, "\\r"); - else if (c == 033) - fprintf (stream, "\\e"); - else if (c == '\a') - fprintf (stream, "\\a"); - else - fprintf (stream, "\\%03o", c); - } - else - { - if (c == '\\' || c == '"' || c == '\'') - fputc ('\\', stream); - fputc (c, stream); - } -} diff --git a/gdb/gdbserver/remote-inflow.c b/gdb/gdbserver/remote-inflow.c index 7e91b3d86fd..931cf2c313b 100644 --- a/gdb/gdbserver/remote-inflow.c +++ b/gdb/gdbserver/remote-inflow.c @@ -17,17 +17,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "defs.h" +#include "server.h" #include "frame.h" #include "inferior.h" -/*************************** -#include "initialize.h" -****************************/ #include #include #include -/*#include */ #define LYNXOS #include #include @@ -43,25 +39,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "/usr/include/wait.h" -/***************Begin MY defs*********************/ -int quit_flag = 0; char registers[REGISTER_BYTES]; -/* Index within `registers' of the first byte of the space for - register N. */ - - -char buf2[MAX_REGISTER_RAW_SIZE]; -/***************End MY defs*********************/ - #include -/*#include */ - -extern char **environ; -extern int errno; -extern int inferior_pid; -void error (), quit (), perror_with_name (); -int query (); /* Start an inferior process and returns its pid. ALLARGS is a vector of program-name and args. @@ -100,9 +80,10 @@ kill_inferior () { if (inferior_pid == 0) return; - ptrace (8, inferior_pid, 0, 0); + ptrace (PTRACE_KILL, inferior_pid, 0, 0); wait (0); - /*************inferior_died ();****VK**************/ + + inferior_pid = 0; } /* Wait for process, returns status */ @@ -114,7 +95,12 @@ mywait (status) int pid; union wait w; + enable_async_io(); + pid = wait (&w); + + disable_async_io(); + if (pid != PIDGET(inferior_pid)) perror_with_name ("wait"); @@ -122,9 +108,9 @@ mywait (status) if (WIFEXITED (w)) { - fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); - *status = 'E'; - return ((unsigned char) WEXITSTATUS (w)); + fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w)); + fprintf (stderr, "GDBserver exiting\n"); + exit (0); } else if (!WIFSTOPPED (w)) { @@ -266,6 +252,7 @@ store_inferior_registers (ignored) /* Copy LEN bytes from inferior's memory starting at MEMADDR to debugger memory starting at MYADDR. */ +void read_inferior_memory (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; @@ -283,7 +270,7 @@ read_inferior_memory (memaddr, myaddr, len) /* Read all the longwords */ for (i = 0; i < count; i++, addr += sizeof (int)) { - buffer[i] = ptrace (1, inferior_pid, addr, 0); + buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); } /* Copy appropriate bytes out of the buffer. */ @@ -313,12 +300,12 @@ write_inferior_memory (memaddr, myaddr, len) /* Fill start and end extra bytes of buffer with existing memory data. */ - buffer[0] = ptrace (1, inferior_pid, addr, 0); + buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); if (count > 1) { buffer[count - 1] - = ptrace (1, inferior_pid, + = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr + (count - 1) * sizeof (int), 0); } @@ -331,22 +318,10 @@ write_inferior_memory (memaddr, myaddr, len) for (i = 0; i < count; i++, addr += sizeof (int)) { errno = 0; - ptrace (4, inferior_pid, addr, buffer[i]); + ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]); if (errno) return errno; } return 0; } - -void -initialize () -{ - inferior_pid = 0; -} - -int -have_inferior_p () -{ - return inferior_pid != 0; -} diff --git a/gdb/gdbserver/remote-server.c b/gdb/gdbserver/remote-server.c index 3d962bcb458..ca8412e1c73 100644 --- a/gdb/gdbserver/remote-server.c +++ b/gdb/gdbserver/remote-server.c @@ -17,37 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "defs.h" -#include -#include - -void read_inferior_memory (); -unsigned char mywait (); -void myresume(); -void initialize (); -int create_inferior (); - -extern char registers[]; -int inferior_pid; -extern char **environ; - -/* Descriptor for I/O to remote machine. */ -int remote_desc; -int kiodebug = 0; -int remote_debugging; - -void remote_send (); -void putpkt (); -void getpkt (); -void remote_open (); -void write_ok (); -void write_enn (); -void convert_ascii_to_int (); -void convert_int_to_ascii (); -void prepare_resume_reply (); -void decode_m_packet (); -void decode_M_packet (); -jmp_buf toplevel; +#include "server.h" main (argc, argv) int argc; @@ -67,9 +37,6 @@ main (argc, argv) if (argc < 3) error("Usage: gdbserver tty prog [args ...]"); - initialize (); - remote_open (argv[1], 0); - inferior_pid = create_inferior (argv[2], &argv[2]); fprintf (stderr, "Process %s created; pid = %d\n", argv[2], inferior_pid); @@ -77,66 +44,72 @@ main (argc, argv) /* We are now stopped at the first instruction of the target process */ - setjmp(toplevel); - do + while (1) { - getpkt (own_buf); - i = 0; - ch = own_buf[i++]; - switch (ch) + remote_open (argv[1]); + + setjmp(toplevel); + while (getpkt (own_buf) > 0) { - case '?': - prepare_resume_reply (own_buf, status, signal); - break; - case 'g': - convert_int_to_ascii (registers, own_buf, REGISTER_BYTES); - break; - case 'G': - convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES); - store_inferior_registers (-1); - write_ok (own_buf); - break; - case 'm': - decode_m_packet (&own_buf[1], &mem_addr, &len); - read_inferior_memory (mem_addr, mem_buf, len); - convert_int_to_ascii (mem_buf, own_buf, len); - break; - case 'M': - decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf); - if (write_inferior_memory (mem_addr, mem_buf, len) == 0) - write_ok (own_buf); - else - write_enn (own_buf); - break; - case 'c': - myresume (0, 0); - signal = mywait (&status); - prepare_resume_reply (own_buf, status, signal); - break; - case 's': - myresume (1, 0); - signal = mywait (&status); - prepare_resume_reply (own_buf, status, signal); - break; - case 'k': - kill_inferior (); - sprintf (own_buf, "q"); + i = 0; + ch = own_buf[i++]; + switch (ch) + { + case '?': + prepare_resume_reply (own_buf, status, signal); + break; + case 'g': + convert_int_to_ascii (registers, own_buf, REGISTER_BYTES); + break; + case 'G': + convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES); + store_inferior_registers (-1); + write_ok (own_buf); + break; + case 'm': + decode_m_packet (&own_buf[1], &mem_addr, &len); + read_inferior_memory (mem_addr, mem_buf, len); + convert_int_to_ascii (mem_buf, own_buf, len); + break; + case 'M': + decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf); + if (write_inferior_memory (mem_addr, mem_buf, len) == 0) + write_ok (own_buf); + else + write_enn (own_buf); + break; + case 'c': + myresume (0, 0); + signal = mywait (&status); + prepare_resume_reply (own_buf, status, signal); + break; + case 's': + myresume (1, 0); + signal = mywait (&status); + prepare_resume_reply (own_buf, status, signal); + break; + case 'k': + fprintf (stderr, "Killing inferior\n"); + kill_inferior (); + inferior_pid = create_inferior (argv[2], &argv[2]); + fprintf (stderr, "Process %s created; pid = %d\n", argv[2], + inferior_pid); + signal = mywait (&status); /* Wait till we are at 1st instr in prog */ + break; + default: + printf ("\nUnknown option chosen by master\n"); + write_enn (own_buf); + break; + } + putpkt (own_buf); - fprintf (stderr, "Obtained kill request...terminating\n"); - close (remote_desc); - exit (0); - default: - printf ("\nUnknown option chosen by master\n"); - write_enn (own_buf); - break; } - putpkt (own_buf); - } - while (1); + /* We come here when getpkt fails. Close the connection, and re-open it + at the top of the loop. */ + + fprintf (stderr, "Remote side has terminated connection. GDBserver will reopen the connection.\n"); - close (remote_desc); - /** now get out of here**/ - fprintf (stderr, "Finished reading data from serial link - Bye!\n"); - exit (0); + remote_close (); + } } -- 2.30.2