summaryrefslogtreecommitdiff
path: root/gdb/top.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2013-04-10 14:10:35 +0000
committerPedro Alves <palves@redhat.com>2013-04-10 14:10:35 +0000
commit9ccb9a101beab4a9794bda91cf4fa0fac529a02f (patch)
treea829f1be25a04e4d5673e0fef78b99cc4dba85bb /gdb/top.c
parentfd3c1b4c0e71d5a18f5d21f3156ac0aa11b04080 (diff)
downloadgdb-9ccb9a101beab4a9794bda91cf4fa0fac529a02f.tar.gz
make -gdb-exit call disconnect_tracing too, and don't lose history if the target errors on "quit"
Gareth mentions in PR gdb/15275: "The MI '-gdb-exit' command mi_cmd_gdb_exit() never calls disconnect_tracing() and therefore exits correctly." It should, so to get out of tfind mode, as quit may detach instead of kill, and we don't want to confuse the memory/register accesses etc. of the detach process. So we should push down the disconnect tracing bits at least to quit_force. But we can't as is, as that would swallow the error thrown by answering "no" to: Trace is running but will stop on detach; detach anyway? (y or n) So to address that, we split disconnect_tracing in two. One part that does the query, and another part that does the rest, and we make quit_force call the latter. Looking at quit_force, it does several things, some of which are a bit independent of the others. It first kills/detaches, and then writes history, and then runs the final cleanups. It seems better to me to do each of these things even if the previous thing throws. E.g., as is, if something throws while detaching, then we skip writing history. Tested on x86_64 Fedora 17. gdb/ 2013-04-10 Pedro Alves <palves@redhat.com> * cli/cli-cmds.c (quit_command): Call query_if_trace_running instead of disconnect_tracing. * infcmd.c (detach_command, disconnect_command): Call query_if_trace_running. Adjust. * top.c: Include "tracepoint.h". (quit_target): Delete. Contents moved ... (quit_force): ... here. Wrap each stage of teardown in TRY_CATCH. Call disconnect_tracing before detaching.
Diffstat (limited to 'gdb/top.c')
-rw-r--r--gdb/top.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/gdb/top.c b/gdb/top.c
index e2c4c61c64a..bc61d3b84c9 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -64,6 +64,7 @@
#include <ctype.h>
#include "ui-out.h"
#include "cli-out.h"
+#include "tracepoint.h"
extern void initialize_all_files (void);
@@ -1282,29 +1283,6 @@ quit_confirm (void)
return qr;
}
-/* Helper routine for quit_force that requires error handling. */
-
-static int
-quit_target (void *arg)
-{
- struct qt_args *qt = (struct qt_args *)arg;
-
- /* Kill or detach all inferiors. */
- iterate_over_inferiors (kill_or_detach, qt);
-
- /* Give all pushed targets a chance to do minimal cleanup, and pop
- them all out. */
- pop_all_targets ();
-
- /* Save the history information if it is appropriate to do so. */
- if (write_history_p && history_filename)
- write_history (history_filename);
-
- do_final_cleanups (all_cleanups ()); /* Do any final cleanups before
- exiting. */
- return 0;
-}
-
/* Quit without asking for confirmation. */
void
@@ -1312,6 +1290,7 @@ quit_force (char *args, int from_tty)
{
int exit_code = 0;
struct qt_args qt;
+ volatile struct gdb_exception ex;
/* An optional expression may be used to cause gdb to terminate with the
value of that expression. */
@@ -1327,9 +1306,46 @@ quit_force (char *args, int from_tty)
qt.args = args;
qt.from_tty = from_tty;
+ /* Wrappers to make the code below a bit more readable. */
+#define DO_TRY \
+ TRY_CATCH (ex, RETURN_MASK_ALL)
+
+#define DO_PRINT_EX \
+ if (ex.reason < 0) \
+ exception_print (gdb_stderr, ex)
+
/* We want to handle any quit errors and exit regardless. */
- catch_errors (quit_target, &qt,
- "Quitting: ", RETURN_MASK_ALL);
+
+ /* Get out of tfind mode, and kill or detach all inferiors. */
+ DO_TRY
+ {
+ disconnect_tracing ();
+ iterate_over_inferiors (kill_or_detach, &qt);
+ }
+ DO_PRINT_EX;
+
+ /* Give all pushed targets a chance to do minimal cleanup, and pop
+ them all out. */
+ DO_TRY
+ {
+ pop_all_targets ();
+ }
+ DO_PRINT_EX;
+
+ /* Save the history information if it is appropriate to do so. */
+ DO_TRY
+ {
+ if (write_history_p && history_filename)
+ write_history (history_filename);
+ }
+ DO_PRINT_EX;
+
+ /* Do any final cleanups before exiting. */
+ DO_TRY
+ {
+ do_final_cleanups (all_cleanups ());
+ }
+ DO_PRINT_EX;
exit (exit_code);
}