From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7028 invoked by alias); 10 Mar 2004 18:02:29 -0000 Mailing-List: contact rda-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: rda-owner@sources.redhat.com Received: (qmail 7018 invoked from network); 10 Mar 2004 18:02:28 -0000 Date: Wed, 10 Mar 2004 18:02:00 -0000 From: Kevin Buettner To: rda@sources.redhat.com Subject: [PATCH] Add attach functionality; use vfork() instead of fork() Message-Id: <20040310110221.7daff289@saguaro> Organization: Red Hat X-Mailer: Sylpheed version 0.9.8claws30 (GTK+ 1.2.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-SW-Source: 2004-q1/txt/msg00001.txt.bz2 I've just committed the following patch to the rda sources. It adds "attach" functionality to rda, allowing the user to use rda to attach to and debug an existing process. It also uses fork() instead of vfork() in order to allow rda to be used on systems which do not support fork(). * ptrace-target.c (ptrace_create_child): Use vfork() instead of fork(). Use PTRACE_ATTACH to attach to an existing process. * server.c (usage): Update to include text about "-a". (main): Allow use of -a switch to attach to an existing process. Index: ptrace-target.c =================================================================== RCS file: /cvs/src/src/rda/unix/ptrace-target.c,v retrieving revision 1.4 diff -u -p -r1.4 ptrace-target.c --- ptrace-target.c 7 Feb 2003 23:03:09 -0000 1.4 +++ ptrace-target.c 10 Mar 2004 17:52:52 -0000 @@ -68,10 +68,12 @@ close_open_files (void) /* ptrace_create_child: - Fork the child process and capture it via ptrace. + Either attach to an existing process or fork a child and capture + it via PTRACE_TRACEME. + + The single argument PROCESS is a struct containing either the + process id to attach to or the file name and arguments to execute. - Args: char *exec_path; \* path to executable file *\ - char **all_args; \* argv array for child. *\ */ /* Local Functions: */ @@ -81,37 +83,51 @@ ptrace_create_child (struct child_proces { int pid; - pid = fork (); - if (pid < 0) + if (process->pid > 0) { - /*perror_with_name ("fork");*/ - fprintf (stderr, "PTRACE: fork failed!\n"); - return 0; - } + pid = process->pid; - if (pid == 0) - { - close_open_files (); - if (process->debug_backend) - fprintf (stderr, "PTRACE_TRACEME\n"); errno = 0; - ptrace (PTRACE_TRACEME, 0L, 0L, 0L); + ptrace (PTRACE_ATTACH, pid, 0L, 0L); if (errno != 0) { - fprintf (stderr, "PTRACE: child cannot be traced!\n"); - goto fail; + fprintf (stderr, "Could not attach to process id %d\n", pid); + exit (1); + } + } + else + { + pid = vfork (); + if (pid < 0) + { + fprintf (stderr, "PTRACE: vfork failed!\n"); + return 0; + } + + if (pid == 0) + { + close_open_files (); + if (process->debug_backend) + fprintf (stderr, "PTRACE_TRACEME\n"); + errno = 0; + ptrace (PTRACE_TRACEME, 0L, 0L, 0L); + if (errno != 0) + { + fprintf (stderr, "PTRACE: child cannot be traced!\n"); + goto fail; + } + if (process->executable != NULL && process->argv != NULL) + execv (process->executable, process->argv); + else + sleep (-1); /* FIXME ??? */ + + fprintf (stderr, "Cannot exec %s: %s.\n", process->executable, + errno > 0 && errno < sys_nerr ? + strerror (errno) : "unknown error"); + fail: + fflush (stderr); + _exit (0177); } - if (process->executable != NULL && process->argv != NULL) - execv (process->executable, process->argv); - else - sleep (-1); /* FIXME ??? */ - - fprintf (stderr, "Cannot exec %s: %s.\n", process->executable, - errno > 0 && errno < sys_nerr ? - strerror (errno) : "unknown error"); - fail: - fflush (stderr); - _exit (0177); } return pid; Index: server.c =================================================================== RCS file: /cvs/src/src/rda/unix/server.c,v retrieving revision 1.2 diff -u -p -r1.2 server.c --- server.c 7 Feb 2003 23:03:09 -0000 1.2 +++ server.c 10 Mar 2004 17:52:52 -0000 @@ -55,10 +55,12 @@ static void usage (char *progname) { fprintf (stderr, - "Usage: %s [-h] [-v] tcp-port-num executable-file [arguments ...]\n\n" + "Usage: %s [-h] [-v] tcp-port-num executable-file [arguments ...]\n" + " or: %s -a [-v] tcp-port-num process-id\n\n" "Start the Red Hat debug agent listening on port ``tcp-port-num'' for\n" "debugging``executable-file'' with optional arguments.\n\n" "Options and arguments:\n" + " -a Attach to already running process.\n" " -h Print this usage message.\n" " -v Increase verbosity. One -v flag enables informational\n" " messages. Two -v flags turn on internal debugging\n" @@ -68,8 +70,9 @@ usage (char *progname) " remote protocol.\n" " executable-file Name of program to debug.\n" " arguments ... Command line arguments with which to start program\n" - " being debugged.\n", - progname); + " being debugged.\n" + " process-id Process ID (PID) of process to attach to.\n", + progname, progname); exit (1); } @@ -79,6 +82,7 @@ main (int argc, char **argv) int portno; char *endptr; int verbose = 0; + int attach = 0; int optidx; struct child_process *process; @@ -89,6 +93,9 @@ main (int argc, char **argv) { switch (argv[optidx][1]) { + case 'a': + attach = 1; + break; case 'h': usage (argv[0]); /* not reached */ @@ -116,8 +123,17 @@ main (int argc, char **argv) process = malloc (sizeof (struct child_process)); memset (process, 0, sizeof (struct child_process)); - process->argv = &argv[optidx + 1]; - process->executable = argv[optidx + 1]; + if (attach) + { + process->pid = strtol (argv[optidx + 1], &endptr, 10); + if (errno != 0 || endptr == argv[optidx] || process->pid <= 0) + usage (argv[0]); + } + else + { + process->argv = &argv[optidx + 1]; + process->executable = argv[optidx + 1]; + } if (verbose > 1) process->debug_backend = 1;