OSDN Git Service

* ptrace-target.c (ptrace_create_child): Use vfork() instead of
authorkevinb <kevinb>
Wed, 10 Mar 2004 17:56:43 +0000 (17:56 +0000)
committerkevinb <kevinb>
Wed, 10 Mar 2004 17:56:43 +0000 (17:56 +0000)
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
rda/unix/ptrace-target.c
rda/unix/server.c

index 64ccbee..e2c844e 100644 (file)
@@ -1,3 +1,10 @@
+2004-03-10  Kevin Buettner  <kevinb@redhat.com>
+
+       * 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  <kevinb@redhat.com>
 
        * config.in (FRV_LINUX_TARGET): Add.
index 3ec0897..a4abda5 100644 (file)
@@ -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;
index 212dc9f..aaeb416 100644 (file)
@@ -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;