From f2706686cf6110debd829ab15dd84fd31425a16c Mon Sep 17 00:00:00 2001 From: kevinb Date: Wed, 10 Mar 2004 17:56:43 +0000 Subject: [PATCH] * 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. --- rda/unix/ChangeLog | 7 +++++ rda/unix/ptrace-target.c | 72 +++++++++++++++++++++++++++++------------------- rda/unix/server.c | 26 +++++++++++++---- 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/rda/unix/ChangeLog b/rda/unix/ChangeLog index 64ccbee7f4..e2c844e783 100644 --- a/rda/unix/ChangeLog +++ b/rda/unix/ChangeLog @@ -1,3 +1,10 @@ +2004-03-10 Kevin Buettner + + * 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. + 2003-11-14 Kevin Buettner * config.in (FRV_LINUX_TARGET): Add. diff --git a/rda/unix/ptrace-target.c b/rda/unix/ptrace-target.c index 3ec0897dd7..a4abda5296 100644 --- a/rda/unix/ptrace-target.c +++ b/rda/unix/ptrace-target.c @@ -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_process *process) { 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; diff --git a/rda/unix/server.c b/rda/unix/server.c index 212dc9ff4a..aaeb41651c 100644 --- a/rda/unix/server.c +++ b/rda/unix/server.c @@ -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; -- 2.11.0