[RFA] gdbserver --attach support

Daniel Jacobowitz
2002-01-17T20:25:07Z

Someone else did this some time ago, but got lost in the paper trail, I
think. This adds '--attach <pid>' as an alternative for 'prog [args...]'.
I only implemented it for Linux, since it's the only one I know the
appropriate ptrace command for with any certainty; other architectures will
still link but report it as unsupported if you try to use --attach.

Is this OK to commit? (Andrew, I guess this one's yours - the only person
who had been watching gdbserver particularly was J.T.).

--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer

2002-01-17 Daniel Jacobowitz <drow@mvista.com>

* low-hppabsd.c (myattach): New function, returning -1.
* low-lynx.c (myattach): Likewise.
* low-nbsd.c (myattach): Likewise.
* low-sim.c (myattach): Likewise.
* low-sparc.c (myattach): Likewise.
* low-sun3.c (myattach): Likewise.

* low-linux.c (myattach): New function.

* server.c (attach_inferior): New function.
(main): Handle "--attach".

Index: gdb/gdbserver/low-hppabsd.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-hppabsd.c,v
retrieving revision 1.9
diff -u -p -r1.9 low-hppabsd.c
--- low-hppabsd.c 2001/07/26 02:23:57 1.9
+++ low-hppabsd.c 2002/01/17 19:31:29
@@ -81,6 +81,13 @@ kill_inferior (void)
/*************inferior_died ();****VK**************/
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (int pid)
Index: gdb/gdbserver/low-linux.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-linux.c,v
retrieving revision 1.12
diff -u -p -r1.12 low-linux.c
--- low-linux.c 2001/12/05 15:11:48 1.12
+++ low-linux.c 2002/01/17 19:31:29
@@ -78,6 +78,23 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attach to an inferior process. */
+
+int
+myattach (int pid)
+{
+ if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
+ {
+ fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid,
+ errno < sys_nerr ? sys_errlist[errno] : "unknown error",
+ errno);
+ fflush (stderr);
+ _exit (0177);
+ }
+
+ return 0;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/low-lynx.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-lynx.c,v
retrieving revision 1.4
diff -u -p -r1.4 low-lynx.c
--- low-lynx.c 2001/07/26 02:23:58 1.4
+++ low-lynx.c 2002/01/17 19:31:29
@@ -87,6 +87,13 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/low-nbsd.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-nbsd.c,v
retrieving revision 1.11
diff -u -p -r1.11 low-nbsd.c
--- low-nbsd.c 2001/07/26 02:23:58 1.11
+++ low-nbsd.c 2002/01/17 19:31:29
@@ -145,6 +145,13 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/low-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-sim.c,v
retrieving revision 1.4
diff -u -p -r1.4 low-sim.c
--- low-sim.c 2001/03/06 08:21:44 1.4
+++ low-sim.c 2002/01/17 19:31:29
@@ -139,6 +139,13 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/low-sparc.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-sparc.c,v
retrieving revision 1.8
diff -u -p -r1.8 low-sparc.c
--- low-sparc.c 2001/07/26 02:23:58 1.8
+++ low-sparc.c 2002/01/17 19:31:29
@@ -75,6 +75,13 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/low-sun3.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/low-sun3.c,v
retrieving revision 1.7
diff -u -p -r1.7 low-sun3.c
--- low-sun3.c 2001/07/26 02:23:58 1.7
+++ low-sun3.c 2002/01/17 19:31:29
@@ -72,6 +72,13 @@ create_inferior (char *program, char **a
return pid;
}

+/* Attaching is not supported. */
+int
+myattach (int pid)
+{
+ return -1;
+}
+
/* Kill the inferior process. Make us have no inferior. */

void
Index: gdb/gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.3
diff -u -p -r1.3 server.c
--- server.c 2001/03/06 08:21:44 1.3
+++ server.c 2002/01/17 19:31:29
@@ -39,6 +39,21 @@ start_inferior (char *argv[], char *stat
return mywait (statusptr);
}

+static int
+attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
+{
+ /* myattach should return -1 if attaching is unsupported,
+ 0 if it succeeded, and call error() otherwise. */
+ if (myattach (pid) != 0)
+ return -1;
+
+ inferior_pid = pid;
+
+ *sigptr = mywait (statusptr);
+
+ return 0;
+}
+
extern int remote_debug;

int
@@ -49,6 +64,10 @@ main (int argc, char *argv[])
unsigned char signal;
unsigned int len;
CORE_ADDR mem_addr;
+ int bad_attach = 0;
+ int pid = 0;
+ int attached = 0;
+ char *arg_end;

if (setjmp (toplevel))
{
@@ -56,15 +75,44 @@ main (int argc, char *argv[])
exit (1);
}

- if (argc < 3)
- error ("Usage: gdbserver tty prog [args ...]");
+ if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
+ {
+ if (argc == 4
+ && argv[3] != '\0'
+ && (pid = strtoul (argv[3], &arg_end, 10)) != 0
+ && *arg_end == '\0')
+ {
+ ;
+ }
+ else
+ bad_attach = 1;
+ }

+ if (argc < 3 || bad_attach)
+ error ("Usage:\tgdbserver tty prog [args ...]\n"
+ "\tgdbserver tty --attach pid");
+
initialize_low ();

- /* Wait till we are at first instruction in program. */
- signal = start_inferior (&argv[2], &status);
+ if (pid == 0)
+ {
+ /* Wait till we are at first instruction in program. */
+ signal = start_inferior (&argv[2], &status);

- /* We are now stopped at the first instruction of the target process */
+ /* We are now stopped at the first instruction of the target process */
+ }
+ else
+ {
+ switch (attach_inferior (pid, &status, &signal))
+ {
+ case -1:
+ error ("Attaching not supported on this target");
+ break;
+ default:
+ attached = 1;
+ break;
+ }
+ }

while (1)
{
@@ -83,8 +131,17 @@ main (int argc, char *argv[])
remote_debug = !remote_debug;
break;
case '!':
- extended_protocol = 1;
- prepare_resume_reply (own_buf, status, signal);
+ if (attached == 0)
+ {
+ extended_protocol = 1;
+ prepare_resume_reply (own_buf, status, signal);
+ }
+ else
+ {
+ /* We can not use the extended protocol if we are
+ attached. */
+ own_buf[0] = '\0';
+ }
break;
case '?':
prepare_resume_reply (own_buf, status, signal);
@@ -250,8 +307,8 @@ main (int argc, char *argv[])
}
else
{
- fprintf (stderr, "Remote side has terminated connection. GDBserver will reopen the connection.\n");
-
+ fprintf (stderr, "Remote side has terminated connection. "
+ "GDBserver will reopen the connection.\n");
remote_close ();
}
}