This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Make sure terminal settings are restored before exiting


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=18206ca3f9367f1488cdfc1475f8da072e7e9636

commit 18206ca3f9367f1488cdfc1475f8da072e7e9636
Author: Patrick Palka <patrick@parcs.ath.cx>
Date:   Mon Jul 27 11:54:07 2015 -0400

    Make sure terminal settings are restored before exiting
    
    When exiting GDB -- whether it's via the "quit" command, via a SIGTERM,
    or otherwise -- we should leave the terminal in the state we acquired
    it.  To that end, we have to undo any modifications that may have been
    made by the TUI (ncurses) or by the CLI (readline).
    
    Tested on x86_64 Debian Stretch.
    
    gdb/ChangeLog:
    
    	* top.c: Include "tui/tui.h".
    	(undo_terminal_modifications_before_exit): New static function.
    	(quit_force): Use it.
    
    gdb/testsuite/ChangeLog:
    
    	* gdb.base/batch-preserve-term-settings.exp
    	(test_terminal_settings_preserved_after_cli_exit): New test.

Diff:
---
 gdb/ChangeLog                                      |  6 ++
 gdb/testsuite/ChangeLog                            |  5 ++
 .../gdb.base/batch-preserve-term-settings.exp      | 94 +++++++++++++++++++++-
 gdb/top.c                                          | 21 +++++
 4 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2e62184..0c24f0c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2015-07-29  Patrick Palka  <patrick@parcs.ath.cx>
 
+	* top.c: Include "tui/tui.h".
+	(undo_terminal_modifications_before_exit): New static function.
+	(quit_force): Use it.
+
+2015-07-29  Patrick Palka  <patrick@parcs.ath.cx>
+
 	* target.c (terminal_state): Initialize to terminal_is_ours.
 
 2015-07-29  Yao Qi  <yao.qi@linaro.org>
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6fd5a36..ee0af2a 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2015-07-29  Patrick Palka  <patrick@parcs.ath.cx>
 
+	* gdb.base/batch-preserve-term-settings.exp
+	(test_terminal_settings_preserved_after_cli_exit): New test.
+
+2015-07-29  Patrick Palka  <patrick@parcs.ath.cx>
+
 	* gdb.base/batch-preserve-term-settings.exp: Remove top-level
 	manipulation of saved_gdbflags.
 	(test_terminal_settings_preserved): Remove global declaration of
diff --git a/gdb/testsuite/gdb.base/batch-preserve-term-settings.exp b/gdb/testsuite/gdb.base/batch-preserve-term-settings.exp
index 97ffaa4..ca6f173 100644
--- a/gdb/testsuite/gdb.base/batch-preserve-term-settings.exp
+++ b/gdb/testsuite/gdb.base/batch-preserve-term-settings.exp
@@ -176,4 +176,96 @@ proc test_terminal_settings_preserved {} {
     exit_shell
 }
 
-test_terminal_settings_preserved
+# Check that quitting from the CLI via the "quit" command does not leave the
+# terminal in the wrong state.  The GDB commands CMDS are executed before
+# quitting.
+
+proc test_terminal_settings_preserved_after_cli_exit { cmds } {
+    global file_arg
+    global GDB INTERNAL_GDBFLAGS GDBFLAGS
+    global gdb_prompt
+    global shell_prompt_re
+
+    if ![spawn_shell] {
+	return
+    }
+
+    set saved_gdbflags $GDBFLAGS
+
+    set stty_supported [run_stty "stty before" stty_before]
+
+    set test "start gdb"
+    send_gdb "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts] --args \"$file_arg\"\n"
+    gdb_expect {
+	-re "$gdb_prompt $" {
+	    pass $test
+	}
+	timeout {
+	    fail "$test (timeout)"
+	}
+	eof {
+	    fail "$test (eof)"
+	}
+    }
+
+    foreach cmd $cmds {
+	set test "run command $cmd"
+	send_gdb "$cmd\n"
+	gdb_expect {
+	    -re "$gdb_prompt $" {
+		pass $test
+	    }
+	    timeout {
+		fail "$test (timeout)"
+	    }
+	    eof {
+		fail "$test (eof)"
+	    }
+	}
+    }
+
+    set test "quit gdb"
+    send_gdb "quit\n"
+    gdb_expect {
+	-re "(y or n)" {
+	    send_gdb "y\n"
+	    exp_continue
+	}
+	-re ".*$shell_prompt_re$" {
+	    pass $test
+	}
+	timeout {
+	    fail "$test (timeout)"
+	}
+	eof {
+	    fail "$test (eof)"
+	}
+    }
+
+    set test "terminal settings preserved"
+    if $stty_supported {
+	run_stty "stty after" stty_after
+
+	gdb_assert [string equal $stty_before $stty_after] $test
+    } else {
+	unsupported "$test (no stty)"
+    }
+
+    exit_shell
+}
+
+with_test_prefix "batch run" {
+    test_terminal_settings_preserved
+}
+
+with_test_prefix "cli exit" {
+    test_terminal_settings_preserved_after_cli_exit { }
+}
+
+with_test_prefix "cli exit after start cmd" {
+    test_terminal_settings_preserved_after_cli_exit { "start" }
+}
+
+with_test_prefix "cli exit after run cmd" {
+    test_terminal_settings_preserved_after_cli_exit { "run" }
+}
diff --git a/gdb/top.c b/gdb/top.c
index 1e30b1c..3e88ac6 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -67,6 +67,10 @@
 #include "tracepoint.h"
 #include "inf-loop.h"
 
+#if defined(TUI)
+# include "tui/tui.h"
+#endif
+
 extern void initialize_all_files (void);
 
 #define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
@@ -1486,6 +1490,21 @@ quit_confirm (void)
   return qr;
 }
 
+/* Prepare to exit GDB cleanly by undoing any changes made to the
+   terminal so that we leave the terminal in the state we acquired it.  */
+
+static void
+undo_terminal_modifications_before_exit (void)
+{
+  target_terminal_ours ();
+#if defined(TUI)
+  tui_disable ();
+#endif
+  if (async_command_editing_p)
+    gdb_disable_readline ();
+}
+
+
 /* Quit without asking for confirmation.  */
 
 void
@@ -1494,6 +1513,8 @@ quit_force (char *args, int from_tty)
   int exit_code = 0;
   struct qt_args qt;
 
+  undo_terminal_modifications_before_exit ();
+
   /* An optional expression may be used to cause gdb to terminate with the 
      value of that expression.  */
   if (args)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]