From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17894 invoked by alias); 28 Mar 2013 18:50:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 17855 invoked by uid 89); 28 Mar 2013 18:50:35 -0000 X-Spam-SWARE-Status: No, score=-8.3 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 28 Mar 2013 18:50:32 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2SIoUlm002870 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 28 Mar 2013 14:50:30 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r2SIoRNT016442; Thu, 28 Mar 2013 14:50:28 -0400 Message-ID: <515490F3.7020308@redhat.com> Date: Thu, 28 Mar 2013 21:11:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130311 Thunderbird/17.0.4 MIME-Version: 1.0 To: gdb-patches@sourceware.org CC: Jan Kratochvil , Gareth McMullin Subject: [PATCH] make -gdb-exit call disconnect_tracing too, and don't lose history if the target errors on "quit" (was: Re: Include putpkt in TRY_CATCH. PR gdb/15275) References: <20130325195832.GA15218@host2.jankratochvil.net> <515478BE.3030801@redhat.com> In-Reply-To: <515478BE.3030801@redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2013-03/txt/msg01071.txt.bz2 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 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 the query, another part 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-03-28 Pedro Alves * 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 tear down in TRY_CATCH. Call disconnect_tracing before detaching. --- gdb/cli/cli-cmds.c | 2 +- gdb/infcmd.c | 7 ++++-- gdb/top.c | 66 ++++++++++++++++++++++++++++++++-------------------- gdb/tracepoint.c | 21 +++++++++++++---- gdb/tracepoint.h | 3 ++ 5 files changed, 65 insertions(+), 34 deletions(-) diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index c05f77f..c4721bd 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -322,7 +322,7 @@ quit_command (char *args, int from_tty) if (!quit_confirm ()) error (_("Not confirmed.")); - disconnect_tracing (from_tty); + query_if_trace_running (from_tty); quit_force (args, from_tty); } diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 0b40f22..ee90f95 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2721,7 +2721,9 @@ detach_command (char *args, int from_tty) if (ptid_equal (inferior_ptid, null_ptid)) error (_("The program is not being run.")); - disconnect_tracing (from_tty); + query_if_trace_running (from_tty); + + disconnect_tracing (); target_detach (args, from_tty); @@ -2751,7 +2753,8 @@ static void disconnect_command (char *args, int from_tty) { dont_repeat (); /* Not for the faint of heart. */ - disconnect_tracing (from_tty); + query_if_trace_running (from_tty); + disconnect_tracing (); target_disconnect (args, from_tty); no_shared_libraries (NULL, from_tty); init_thread_list (); diff --git a/gdb/top.c b/gdb/top.c index e2c4c61..bc61d3b 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -64,6 +64,7 @@ #include #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); } diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 9a2425b..04125fb 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -2211,12 +2211,15 @@ trace_status_mi (int on_stop) } } -/* This function handles the details of what to do about an ongoing - tracing run if the user has asked to detach or otherwise disconnect - from the target. */ +/* Check if a trace run is ongoing. If so, and FROM_TTY, query the + user if she really wants to detach. */ + void -disconnect_tracing (int from_tty) +query_if_trace_running (int from_tty) { + if (!from_tty) + return; + /* It can happen that the target that was tracing went away on its own, and we didn't notice. Get a status update, and if the current target doesn't even do tracing, then assume it's not @@ -2229,7 +2232,7 @@ disconnect_tracing (int from_tty) just going to disconnect and let the target deal with it, according to how it's been instructed previously via disconnected-tracing. */ - if (current_trace_status ()->running && from_tty) + if (current_trace_status ()->running) { process_tracepoint_on_disconnect (); @@ -2246,7 +2249,15 @@ disconnect_tracing (int from_tty) error (_("Not confirmed.")); } } +} +/* This function handles the details of what to do about an ongoing + tracing run if the user has asked to detach or otherwise disconnect + from the target. */ + +void +disconnect_tracing (void) +{ /* Also we want to be out of tfind mode, otherwise things can get confusing upon reconnection. Just use these calls instead of full tfind_1 behavior because we're in the middle of detaching, diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index c7eef7b..f603c75 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -372,7 +372,8 @@ extern struct tracepoint *create_tracepoint_from_upload (struct uploaded_tp *utp extern void merge_uploaded_tracepoints (struct uploaded_tp **utpp); extern void merge_uploaded_trace_state_variables (struct uploaded_tsv **utsvp); -extern void disconnect_tracing (int from_tty); +extern void query_if_trace_running (int from_tty); +extern void disconnect_tracing (void); extern void start_tracing (char *notes); extern void stop_tracing (char *notes);