aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog18
-rw-r--r--gdb/NEWS6
-rw-r--r--gdb/gdbserver/ChangeLog9
-rw-r--r--gdb/gdbserver/linux-low.c18
-rw-r--r--gdb/gdbserver/server.c22
-rw-r--r--gdb/gdbserver/target.h7
-rw-r--r--gdb/infcmd.c27
-rw-r--r--gdb/mi/ChangeLog4
-rw-r--r--gdb/mi/mi-cmds.c1
-rw-r--r--gdb/remote.c20
-rw-r--r--gdb/target.c26
-rw-r--r--gdb/target.h6
12 files changed, 154 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e972edc..dfae4df 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,23 @@
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.
(insert_breakpoints): Use catch_exceptions to call
insert_catchpoint. Disable catchpoints if they fail to insert.
diff --git a/gdb/NEWS b/gdb/NEWS
index 98aab4f..10cd468 100644
--- 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
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 8e95517..c865334 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -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>:
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 4ad204e..c700d40 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -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,
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index d0963ba..81fde5b 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -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)
{
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index c09ac8d..1c47a3ae 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -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)
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 0ed0ce2..911e865 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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.");
diff --git a/gdb/mi/ChangeLog b/gdb/mi/ChangeLog
index 57651c2..ed861f0 100644
--- a/gdb/mi/ChangeLog
+++ b/gdb/mi/ChangeLog
@@ -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.
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 9ec174f..9182402 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -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},
diff --git a/gdb/remote.c b/gdb/remote.c
index 3de323b..492661b 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -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;
diff --git a/gdb/target.c b/gdb/target.c
index fd0165a..e738208 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -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);
@@ -1141,6 +1147,16 @@ target_detach (char *args, int 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)
{
if (STREQ (current_target.to_shortname, "rombug"))
@@ -1562,6 +1578,15 @@ debug_to_detach (char *args, int 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)
{
debug_target.to_resume (ptid, step, 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;
diff --git a/gdb/target.h b/gdb/target.h
index c2d8793..a3e10e8 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -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