From patchwork Tue Nov 25 20:50:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 3913 Received: (qmail 9874 invoked by alias); 25 Nov 2014 20:50:29 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 9861 invoked by uid 89); 25 Nov 2014 20:50:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL, BAYES_05, SPF_PASS autolearn=ham version=3.3.2 X-HELO: usevmg20.ericsson.net Received: from usevmg20.ericsson.net (HELO usevmg20.ericsson.net) (198.24.6.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 25 Nov 2014 20:50:26 +0000 Received: from EUSAAHC007.ericsson.se (Unknown_Domain [147.117.188.93]) by usevmg20.ericsson.net (Symantec Mail Security) with SMTP id 72.E7.05330.82294745; Tue, 25 Nov 2014 15:28:56 +0100 (CET) Received: from simark-hp.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.93) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 25 Nov 2014 15:50:23 -0500 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH] Restore terminal state in mi_thread_exit (PR gdb/17627) Date: Tue, 25 Nov 2014 15:50:12 -0500 Message-ID: <1416948612-5781-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 X-IsSubscribed: yes When a thread exits, the terminal is left in mode "terminal_is_ours" while the target executes. This patch fixes that. From my understanding, a function calling target_terminal_ours expects that the terminal could be in any state at the moment it is called. Therefore, it should be its reponsibility to put back the terminal in whatever state it was before being called. I find that this fits quite well the cleanup model, so I implemented a cleanup for that. gdb/ChangeLog: 2014-11-25 Simon Marchi PR gdb/17627 * target.c (cleanup_restore_target_terminal): New function. (make_cleanup_restore_target_terminal): New function. * target.h (make_cleanup_restore_target_terminal): New declaration. * mi/mi-interp.c (mi_thread_exit): Use the new cleanup. Signed-off-by: Simon Marchi --- gdb/mi/mi-interp.c | 4 ++++ gdb/target.c | 30 ++++++++++++++++++++++++++++++ gdb/target.h | 4 ++++ 3 files changed, 38 insertions(+) diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index df2b558..2a62e22 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -386,6 +386,7 @@ mi_thread_exit (struct thread_info *t, int silent) { struct mi_interp *mi; struct inferior *inf; + struct cleanup *old_chain; if (silent) return; @@ -393,11 +394,14 @@ mi_thread_exit (struct thread_info *t, int silent) inf = find_inferior_pid (ptid_get_pid (t->ptid)); mi = top_level_interpreter_data (); + old_chain = make_cleanup_restore_target_terminal(); target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "thread-exited,id=\"%d\",group-id=\"i%d\"", t->num, inf->num); gdb_flush (mi->event_channel); + + do_cleanups(old_chain); } /* Emit notification on changing the state of record. */ diff --git a/gdb/target.c b/gdb/target.c index ab5f2b9..d6a06bd 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -528,6 +528,36 @@ target_supports_terminal_ours (void) return 0; } +static void cleanup_restore_target_terminal (void *arg) +{ + enum terminal_state *previous_state = arg; + + switch (*previous_state) + { + case terminal_is_ours: + target_terminal_ours(); + break; + case terminal_is_ours_for_output: + target_terminal_ours_for_output(); + break; + case terminal_is_inferior: + target_terminal_inferior(); + break; + } + + xfree(previous_state); +} + +struct cleanup * +make_cleanup_restore_target_terminal (void) +{ + enum terminal_state *ts = xmalloc(sizeof(*ts)); + + *ts = terminal_state; + + return make_cleanup (cleanup_restore_target_terminal, ts); +} + static void tcomplain (void) { diff --git a/gdb/target.h b/gdb/target.h index d363b61..a1c3b7b 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1413,6 +1413,10 @@ extern void target_terminal_ours (void); extern int target_supports_terminal_ours (void); +/* Make a cleanup that restores the state of the terminal to the current + * value. */ +extern struct cleanup *make_cleanup_restore_target_terminal (void); + /* Print useful information about our terminal status, if such a thing exists. */