📄 rem-multi.shar
字号:
#!/bin/sh# This is a shell archive.# Run the file through sh to extract its contents.# shar: Shell Archiver# Run the following text with /bin/sh to create:# Remote_Makefile# remote_gutils.c# remote_inflow.c# remote_server.c# remote_utils.c# This archive created: Fri Jun 23 17:06:55 1989cat << \SHAR_EOF > Remote_Makefile# Makefile for the remote server for GDB, the GNU debugger.# Copyright (C) 1986, 1989 Free Software Foundation, Inc.# # This file is part of GDB.# # This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.# # This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.# # 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.CFLAGS = -g CC = ccSERVER = remote_server.o\ remote_inflow.o\ remote_utils.o\ remote_gutils.o prog : $(SERVER) $(CC) -g -o serve $(SERVER) SHAR_EOFcat << \SHAR_EOF > remote_gutils.c/* General utility routines for the remote server for GDB, the GNU debugger. Copyright (C) 1986, 1989 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <sys/ioctl.h>#include "defs.h"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) (); int 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. */voiddo_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. */voiddiscard_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. */voidfree_current_contents (location) char **location;{ free (*location);}/* Generally useful subroutines used throughout the program. *//* Like malloc but get error if no storage available. */char *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. */char *xrealloc (ptr, size) char *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. */voidperror_with_name (string) char *string;{ extern int sys_nerr; extern char *sys_errlist[]; extern int errno; char *err; char *combined; if (errno < sys_nerr) err = sys_errlist[errno]; else err = "unknown error"; combined = (char *) alloca (strlen (err) + strlen (string) + 3); strcpy (combined, string); strcat (combined, ": "); strcat (combined, err); error ("%s.", combined);}/* Print the system error message for ERRCODE, and also mention STRING as the file name for which the error was encountered. */voidprint_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);}voidquit (){ fflush (stdout); ioctl (fileno (stdout), TIOCFLUSH, 0); error ("Quit");}/* Control C comes here */voidrequest_quit (){ 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. */voiderror (string, arg1, arg2, arg3) char *string; int arg1, arg2, arg3;{ fflush (stdout); fprintf (stderr, string, arg1, arg2, arg3); fprintf (stderr, "\n"); /************return_to_top_level ();************/ }/* Print an error message and exit reporting failure. This is for a error that we cannot continue from. STRING and ARG are passed to fprintf. */voidfatal (string, arg) char *string; int arg;{ fprintf (stderr, "gdb: "); fprintf (stderr, 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) char *ptr; int size;{ register char *p = (char *) xmalloc (size + 1); bcopy (ptr, p, size); p[size] = 0; return p;}voidprint_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. */intquery (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. */intparse_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; }}voidprintchar (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); }}SHAR_EOFcat << \SHAR_EOF > remote_inflow.c/* Low level interface to ptrace, for GDB when running under Unix. Copyright (C) 1986, 1987 Free Software Foundation, Inc.*/#include "defs.h"#include "param.h"#include "wait.h"#include "frame.h"#include "inferior.h"/***************************#include "initialize.h"****************************/ #include <stdio.h>#include <sys/param.h>#include <sys/dir.h>#include <sys/user.h>#include <signal.h>#include <sys/ioctl.h>#include <sgtty.h>#include <fcntl.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*********************/ #ifdef NEW_SUN_PTRACE#include <sys/ptrace.h>#include <machine/reg.h>#endifextern char **environ; extern int errno;extern int inferior_pid; void error(), quit(), perror_with_name();int query(); void supply_register(), write_register(); CORE_ADDR read_register(); /* Nonzero if we are debugging an attached outside process rather than an inferior. *//* Start an inferior process and returns its pid. ALLARGS is a vector of program-name and args. ENV is the environment vector to pass. */intcreate_inferior (allargs, env) char **allargs; char **env;{ int pid; extern int sys_nerr; extern char *sys_errlist[]; extern int errno; /* exec is said to fail if the executable is open. */ /****************close_exec_file ();*****************/ pid = vfork (); if (pid < 0) perror_with_name ("vfork"); if (pid == 0) { /* Run inferior in a separate process group. */ setpgrp (getpid (), getpid ());/* Not needed on Sun, at least, and loses there because it clobbers the superior. *//*??? signal (SIGQUIT, SIG_DFL); signal (SIGINT, SIG_DFL); */ errno = 0; ptrace (0); execle ("/bin/sh", "sh", "-c", allargs, 0, env); fprintf (stderr, "Cannot exec /bin/sh: %s.\n", errno < sys_nerr ? sys_errlist[errno] : "unknown error"); fflush (stderr); _exit (0177); } return pid;}/* Kill the inferior process. Make us have no inferior. */kill_inferior (){ if (inferior_pid == 0) return; ptrace (8, inferior_pid, 0, 0); wait (0); /*************inferior_died ();****VK**************/ }/* Resume execution of the inferior process. If STEP is nonzero, single-step it. If SIGNAL is nonzero, give it that signal. */unsigned charresume (step, signal,status) int step; int signal; char *status; { int pid ; WAITTYPE w; errno = 0; ptrace (step ? 9 : 7, inferior_pid, 1, signal); if (errno) perror_with_name ("ptrace"); pid = wait(&w); if(pid != inferior_pid) perror_with_name ("wait"); if(WIFEXITED(w)) { printf("\nchild exited with retcode = %x \n",WRETCODE(w)); *status = 'E'; return((unsigned char) WRETCODE(w)); } else if(!WIFSTOPPED(w)) { printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); *status = 'T'; return((unsigned char) WTERMSIG(w)); } else { printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); *status = 'S'; return((unsigned char) WSTOPSIG(w)); } }#ifdef NEW_SUN_PTRACEvoidfetch_inferior_registers (){ struct regs inferior_registers; struct fp_status inferior_fp_registers; extern char registers[]; ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers); if (errno) perror_with_name ("ptrace"); /**********debugging begin **********/ print_some_registers(&inferior_registers); /**********debugging end **********/ ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers); if (errno) perror_with_name ("ptrace"); bcopy (&inferior_registers, registers, 16 * 4); bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], sizeof inferior_fp_registers.fps_regs); *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; bcopy (&inferior_fp_registers.fps_control, ®isters[REGISTER_BYTE (FPC_REGNUM)], sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);}/* Store our register values back into the inferior. If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */store_inferior_registers (regno) int regno;{ struct regs inferior_registers; struct fp_status inferior_fp_registers; extern char registers[]; bcopy (registers, &inferior_registers, 16 * 4); bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, sizeof inferior_fp_registers.fps_regs); inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)], &inferior_fp_registers.fps_control, sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs); ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers); if (errno)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -