gdb/
authorDaniel Jacobowitz <drow@false.org>
Tue, 17 Jun 2003 20:28:14 +0000 (20:28 +0000)
committerDaniel Jacobowitz <drow@false.org>
Tue, 17 Jun 2003 20:28:14 +0000 (20:28 +0000)
        * NEWS: Mention gdbserver detach change and "disconnect" command.
        * infcmd.c (disconnect_command): New function.
        (_initialize_infcmd): Add ``disconnect'' command.
        * remote.c (remote_async_detach): Delete.
        (remote_detach): Merge remote_async_detach.
        (remote_disconnect): New.
        (init_remote_ops): Set to_disconnect.
        (init_remote_cisco_ops): Likewise.
        (init_remote_async_ops): Likewise.  Use remote_detach.
        * target.c (cleanup_target): Default to_disconnect.
        (update_current_target): Inherit to_disconnect.
        (target_disconnect, debug_to_disconnect): New functions.
        (setup_target_debug): Set to_disconnect.
        * target.h (struct target_ops): Add to_disconnect.
        (target_disconnect): Add prototype.
gdbserver/
* linux-low.c: Move comment to linux_thread_alive where it belonged.
(linux_detach_one_process, linux_detach): New functions.
(linux_target_ops): Add linux_detach.
* server.c (main): Handle 'D' packet.
* target.h (struct target_ops): Add "detach" member.
(detach_inferior): Define.
mi/
        * mi-cmds.c (mi_cmds): Add "-target-disconnect".

12 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/target.h
gdb/infcmd.c
gdb/mi/ChangeLog
gdb/mi/mi-cmds.c
gdb/remote.c
gdb/target.c
gdb/target.h

index e972edcb16b06121065e81fe99428454b0cda8fe..dfae4df12ed205c4999ab577fc311d83a398336f 100644 (file)
@@ -1,3 +1,21 @@
+2003-06-17  Daniel Jacobowitz  <drow@mvista.com>
+
+        * NEWS: Mention gdbserver detach change and "disconnect" command.
+        * infcmd.c (disconnect_command): New function.
+        (_initialize_infcmd): Add ``disconnect'' command.
+        * remote.c (remote_async_detach): Delete.
+        (remote_detach): Merge remote_async_detach.
+        (remote_disconnect): New.
+        (init_remote_ops): Set to_disconnect.
+        (init_remote_cisco_ops): Likewise.
+        (init_remote_async_ops): Likewise.  Use remote_detach.
+        * target.c (cleanup_target): Default to_disconnect.
+        (update_current_target): Inherit to_disconnect.
+        (target_disconnect, debug_to_disconnect): New functions.
+        (setup_target_debug): Set to_disconnect.
+        * target.h (struct target_ops): Add to_disconnect.
+        (target_disconnect): Add prototype.
+
 2003-06-17  Daniel Jacobowitz  <drow@mvista.com>
 
        * breakpoint.c (insert_catchpoint): New function.
index 98aab4fe1e8341bfa80f0aa76ba22e3459c26f7c..10cd468d51c42fb651237bf64220a2a71164323f 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,12 @@
 
 *** Changes since GDB 5.3:
 
+* The meaning of "detach" has changed for gdbserver
+
+The "detach" command will now resume the application, as documented.  To
+disconnect from gdbserver and leave it stopped, use the new "disconnect"
+command.
+
 * d10v `regs' command deprecated
 
 The `info registers' command has been updated so that it displays the
index 8e9551715aa8a5d844a88899c39ced0578f72908..c86533457e21967360e6c2011a1b2d991c3cc882 100644 (file)
@@ -1,3 +1,12 @@
+2003-06-17  Daniel Jacobowitz  <drow@mvista.com>
+
+       * linux-low.c: Move comment to linux_thread_alive where it belonged.
+       (linux_detach_one_process, linux_detach): New functions.
+       (linux_target_ops): Add linux_detach.
+       * server.c (main): Handle 'D' packet.
+       * target.h (struct target_ops): Add "detach" member.
+       (detach_inferior): Define.
+
 2003-06-13  Mark Kettenis  <kettenis@gnu.org>
 
        From Kelley Cook  <kelleycook@wideopenwest.com>:
index 4ad204ed3acec687bf750337d5b5365b73aeeecf..c700d40ba3ac160f2e28d324cd354b53917229f5 100644 (file)
@@ -234,13 +234,28 @@ linux_kill_one_process (struct inferior_list_entry *entry)
     } while (WIFSTOPPED (wstat));
 }
 
-/* Return nonzero if the given thread is still alive.  */
 static void
 linux_kill (void)
 {
   for_each_inferior (&all_threads, linux_kill_one_process);
 }
 
+static void
+linux_detach_one_process (struct inferior_list_entry *entry)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct process_info *process = get_thread_process (thread);
+
+  ptrace (PTRACE_DETACH, pid_of (process), 0, 0);
+}
+
+static void
+linux_detach (void)
+{
+  for_each_inferior (&all_threads, linux_detach_one_process);
+}
+
+/* Return nonzero if the given thread is still alive.  */
 static int
 linux_thread_alive (int tid)
 {
@@ -1249,6 +1264,7 @@ static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_attach,
   linux_kill,
+  linux_detach,
   linux_thread_alive,
   linux_resume,
   linux_wait,
index d0963ba9de994f40459829aa9c5f763c5efff149..81fde5b7f73e8f1b3f9c1d0fac31f5e21ca87942 100644 (file)
@@ -217,6 +217,28 @@ main (int argc, char *argv[])
            case 'd':
              remote_debug = !remote_debug;
              break;
+           case 'D':
+             fprintf (stderr, "Detaching from inferior\n");
+             detach_inferior ();
+             write_ok (own_buf);
+             putpkt (own_buf);
+             remote_close ();            
+
+             /* If we are attached, then we can exit.  Otherwise, we need to
+                hang around doing nothing, until the child is gone.  */
+             if (!attached)
+               {
+                 int status, ret;
+
+                 do {
+                   ret = waitpid (signal_pid, &status, 0);
+                   if (WIFEXITED (status) || WIFSIGNALED (status))
+                     break;
+                 } while (ret != -1 || errno != ECHILD);
+               }
+
+             exit (0);
+
            case '!':
              if (attached == 0)
                {
index c09ac8da73ddb9496c32563b553b4593acbff93d..1c47a3aedb3b325a2d266c03e2f59fe6d396742a 100644 (file)
@@ -48,6 +48,10 @@ struct target_ops
 
   void (*kill) (void);
 
+  /* Detach from all inferiors.  */
+
+  void (*detach) (void);
+
   /* Return 1 iff the thread with process ID PID is alive.  */
 
   int (*thread_alive) (int pid);
@@ -122,6 +126,9 @@ void set_target_ops (struct target_ops *);
 #define kill_inferior() \
   (*the_target->kill) ()
 
+#define detach_inferior() \
+  (*the_target->detach) ()
+
 #define mythread_alive(pid) \
   (*the_target->thread_alive) (pid)
 
index 0ed0ce2f080510e8a29bb9f3aefbbf3c8484b7c4..911e865cf4e845d86142ee8777edef12956a5482 100644 (file)
@@ -81,6 +81,8 @@ static void float_info (char *, int);
 
 static void detach_command (char *, int);
 
+static void disconnect_command (char *, int);
+
 static void unset_environment_command (char *, int);
 
 static void set_environment_command (char *, int);
@@ -1876,6 +1878,26 @@ detach_command (char *args, int from_tty)
     detach_hook ();
 }
 
+/* Disconnect from the current target without resuming it (leaving it
+   waiting for a debugger).
+
+   We'd better not have left any breakpoints in the program or the
+   next debugger will get confused.  Currently only supported for some
+   remote targets, since the normal attach mechanisms don't work on
+   stopped processes on some native platforms (e.g. GNU/Linux).  */
+
+static void
+disconnect_command (char *args, int from_tty)
+{
+  dont_repeat ();              /* Not for the faint of heart */
+  target_disconnect (args, from_tty);
+#if defined(SOLIB_RESTART)
+  SOLIB_RESTART ();
+#endif
+  if (detach_hook)
+    detach_hook ();
+}
+
 /* Stop the execution of the target while running in async mode, in
    the backgound. */
 void
@@ -2014,6 +2036,11 @@ to specify the program, and to load its symbol table.");
 If a process, it is no longer traced, and it continues its execution.  If\n\
 you were debugging a file, the file is closed and gdb no longer accesses it.");
 
+  add_com ("disconnect", class_run, disconnect_command,
+          "Disconnect from a target.\n\
+The target will wait for another debugger to connect.  Not available for\n\
+all targets.");
+
   add_com ("signal", class_run, signal_command,
           "Continue program giving it signal specified by the argument.\n\
 An argument of \"0\" means continue program without giving it a signal.");
index 57651c2d16a165dc429862a08847bd365012b376..ed861f023bc8ea080c7c1dac3b69f6405e9aafca 100644 (file)
@@ -1,3 +1,7 @@
+2003-06-17  Daniel Jacobowitz  <drow@mvista.com>
+
+        * mi-cmds.c (mi_cmds): Add "-target-disconnect".
+
 2003-06-11  David Carlton  <carlton@bactrian.org>
 
        * mi-cmd-stack.c: Include dictionary.h.
index 9ec174fd854ca6c3eef6f2e4e14994d73d97b0e7..91824022278d979c07abdea36ea82f4b4d5c8a5d 100644 (file)
@@ -127,6 +127,7 @@ struct mi_cmd mi_cmds[] =
   {"target-attach", 0, 0},
   {"target-compare-sections", 0, 0},
   {"target-detach", "detach", 0},
+  {"target-disconnect", "disconnect", 0},
   {"target-download", 0, mi_cmd_target_download},
   {"target-exec-status", 0, 0},
   {"target-list-available-targets", 0, 0},
index 3de323ba7fda3fc8bed5105f7f24bd3d61441206..492661b67253be6cbf17c68a5c7acf4f9e93b756 100644 (file)
@@ -126,7 +126,6 @@ static void remote_async_kill (void);
 static int tohex (int nib);
 
 static void remote_detach (char *args, int from_tty);
-static void remote_async_detach (char *args, int from_tty);
 
 static void remote_interrupt (int signo);
 
@@ -2421,15 +2420,19 @@ remote_detach (char *args, int from_tty)
   strcpy (buf, "D");
   remote_send (buf, (rs->remote_packet_size));
 
+  /* Unregister the file descriptor from the event loop. */
+  if (target_is_async_p ())
+    serial_async (remote_desc, NULL, 0);
+
   target_mourn_inferior ();
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
-
 }
 
-/* Same as remote_detach, but with async support. */
+/* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
+
 static void
-remote_async_detach (char *args, int from_tty)
+remote_disconnect (char *args, int from_tty)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
@@ -2437,10 +2440,6 @@ remote_async_detach (char *args, int from_tty)
   if (args)
     error ("Argument given to \"detach\" when remotely debugging.");
 
-  /* Tell the remote target to detach.  */
-  strcpy (buf, "D");
-  remote_send (buf, (rs->remote_packet_size));
-
   /* Unregister the file descriptor from the event loop. */
   if (target_is_async_p ())
     serial_async (remote_desc, NULL, 0);
@@ -5438,6 +5437,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_open = remote_open;
   remote_ops.to_close = remote_close;
   remote_ops.to_detach = remote_detach;
+  remote_ops.to_disconnect = remote_disconnect;
   remote_ops.to_resume = remote_resume;
   remote_ops.to_wait = remote_wait;
   remote_ops.to_fetch_registers = remote_fetch_registers;
@@ -5858,6 +5858,7 @@ Specify the serial device it is connected to (e.g. host:2020).";
   remote_cisco_ops.to_open = remote_cisco_open;
   remote_cisco_ops.to_close = remote_cisco_close;
   remote_cisco_ops.to_detach = remote_detach;
+  remote_cisco_ops.to_disconnect = remote_disconnect;
   remote_cisco_ops.to_resume = remote_resume;
   remote_cisco_ops.to_wait = remote_cisco_wait;
   remote_cisco_ops.to_fetch_registers = remote_fetch_registers;
@@ -5953,7 +5954,8 @@ init_remote_async_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_async_ops.to_open = remote_async_open;
   remote_async_ops.to_close = remote_close;
-  remote_async_ops.to_detach = remote_async_detach;
+  remote_async_ops.to_detach = remote_detach;
+  remote_async_ops.to_disconnect = remote_disconnect;
   remote_async_ops.to_resume = remote_async_resume;
   remote_async_ops.to_wait = remote_async_wait;
   remote_async_ops.to_fetch_registers = remote_fetch_registers;
index fd0165a19ba9129011486db90892eb50cb445ccb..e7382081b9b09016e618392961f48dc2d0bdfcf3 100644 (file)
@@ -95,6 +95,8 @@ static void debug_to_attach (char *, int);
 
 static void debug_to_detach (char *, int);
 
+static void debug_to_disconnect (char *, int);
+
 static void debug_to_resume (ptid_t, int, enum target_signal);
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
@@ -371,6 +373,9 @@ cleanup_target (struct target_ops *t)
   de_fault (to_detach, 
            (void (*) (char *, int)) 
            target_ignore);
+  de_fault (to_disconnect, 
+           (void (*) (char *, int)) 
+           tcomplain);
   de_fault (to_resume, 
            (void (*) (ptid_t, int, enum target_signal)) 
            noprocess);
@@ -556,6 +561,7 @@ update_current_target (void)
       INHERIT (to_attach, t);
       INHERIT (to_post_attach, t);
       INHERIT (to_detach, t);
+      INHERIT (to_disconnect, t);
       INHERIT (to_resume, t);
       INHERIT (to_wait, t);
       INHERIT (to_post_wait, t);
@@ -1140,6 +1146,16 @@ target_detach (char *args, int from_tty)
   (current_target.to_detach) (args, from_tty);
 }
 
+void
+target_disconnect (char *args, int from_tty)
+{
+  /* Handle any optimized stores to the inferior.  */
+#ifdef DO_DEFERRED_STORES
+  DO_DEFERRED_STORES;
+#endif
+  (current_target.to_disconnect) (args, from_tty);
+}
+
 void
 target_link (char *modname, CORE_ADDR *t_reloc)
 {
@@ -1561,6 +1577,15 @@ debug_to_detach (char *args, int from_tty)
   fprintf_unfiltered (gdb_stdlog, "target_detach (%s, %d)\n", args, from_tty);
 }
 
+static void
+debug_to_disconnect (char *args, int from_tty)
+{
+  debug_target.to_disconnect (args, from_tty);
+
+  fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
+                     args, from_tty);
+}
+
 static void
 debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
@@ -2202,6 +2227,7 @@ setup_target_debug (void)
   current_target.to_attach = debug_to_attach;
   current_target.to_post_attach = debug_to_post_attach;
   current_target.to_detach = debug_to_detach;
+  current_target.to_disconnect = debug_to_disconnect;
   current_target.to_resume = debug_to_resume;
   current_target.to_wait = debug_to_wait;
   current_target.to_post_wait = debug_to_post_wait;
index c2d87937dada86ea512a462f23d1dea96a5f611e..a3e10e8ddd099953484c1151824f321801358f10 100644 (file)
@@ -198,6 +198,7 @@ struct target_ops
     void (*to_attach) (char *, int);
     void (*to_post_attach) (int);
     void (*to_detach) (char *, int);
+    void (*to_disconnect) (char *, int);
     void (*to_resume) (ptid_t, int, enum target_signal);
     ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
     void (*to_post_wait) (ptid_t, int);
@@ -414,6 +415,11 @@ extern struct target_stack_item *target_stack;
 
 extern void target_detach (char *, int);
 
+/* Disconnect from the current target without resuming it (leaving it
+   waiting for a debugger).  */
+
+extern void target_disconnect (char *, int);
+
 /* Resume execution of the target process PTID.  STEP says whether to
    single-step or to run free; SIGGNAL is the signal to be given to
    the target, or TARGET_SIGNAL_0 for no signal.  The caller may not