+2016-08-23 Pedro Alves <palves@redhat.com>
+
+ PR gdb/20494
+ * inflow.c (our_terminal_info, initial_gdb_ttystate): Update
+ comments.
+ (enum gdb_has_a_terminal_flag_enum, gdb_has_a_terminal_flag):
+ Delete.
+ (set_initial_gdb_ttystate): Record our_terminal_info here too,
+ instead of ...
+ (gdb_has_a_terminal): ... here. Reimplement in terms of
+ initial_gdb_ttystate. Make static.
+ * terminal.h (gdb_has_a_terminal): Delete declaration.
+ (set_initial_gdb_ttystate): Add comment.
+ * top.c (show_interactive_mode): Use input_interactive_p instead
+ of gdb_has_a_terminal.
+
2016-08-22 Pedro Alves <palves@redhat.com>
PR gdb/20505
};
/* Our own tty state, which we restore every time we need to deal with
- the terminal. This is only set once, when GDB first starts. The
- settings of flags which readline saves and restores and
+ the terminal. This is set once, when GDB first starts, and then
+ whenever we enter/leave TUI mode (gdb_save_tty_state). The
+ settings of flags which readline saves and restores are
unimportant. */
static struct terminal_info our_terminal_info;
-/* Snapshot of our own tty state taken during initialization of GDB.
- This is used as the initial tty state given to each new inferior. */
+/* Snapshot of the initial tty state taken during initialization of
+ GDB, before readline/ncurses have had a chance to change it. This
+ is used as the initial tty state given to each new spawned
+ inferior. Unlike our_terminal_info, this is only ever set
+ once. */
static serial_ttystate initial_gdb_ttystate;
static struct terminal_info *get_inflow_inferior_data (struct inferior *);
}
#endif
-enum gdb_has_a_terminal_flag_enum
- {
- yes, no, have_not_checked
- }
-gdb_has_a_terminal_flag = have_not_checked;
-
-/* Set the initial tty state that is to be inherited by new inferiors. */
+/* See terminal.h. */
void
set_initial_gdb_ttystate (void)
{
+ /* Note we can't do any of this in _initialize_inflow because at
+ that point stdin_serial has not been created yet. */
+
initial_gdb_ttystate = serial_get_tty_state (stdin_serial);
-}
-/* Does GDB have a terminal (on stdin)? */
-int
-gdb_has_a_terminal (void)
-{
- switch (gdb_has_a_terminal_flag)
+ if (initial_gdb_ttystate != NULL)
{
- case yes:
- return 1;
- case no:
- return 0;
- case have_not_checked:
- /* Get all the current tty settings (including whether we have a
- tty at all!). Can't do this in _initialize_inflow because
- serial_fdopen() won't work until the serial_ops_list is
- initialized. */
-
+ our_terminal_info.ttystate
+ = serial_copy_tty_state (stdin_serial, initial_gdb_ttystate);
#ifdef F_GETFL
our_terminal_info.tflags = fcntl (0, F_GETFL, 0);
#endif
-
- gdb_has_a_terminal_flag = no;
- if (stdin_serial != NULL)
- {
- our_terminal_info.ttystate = serial_get_tty_state (stdin_serial);
-
- if (our_terminal_info.ttystate != NULL)
- {
- gdb_has_a_terminal_flag = yes;
#ifdef PROCESS_GROUP_TYPE
- our_terminal_info.process_group = gdb_getpgrp ();
+ our_terminal_info.process_group = gdb_getpgrp ();
#endif
- }
- }
-
- return gdb_has_a_terminal_flag == yes;
- default:
- /* "Can't happen". */
- return 0;
}
}
+/* Does GDB have a terminal (on stdin)? */
+
+static int
+gdb_has_a_terminal (void)
+{
+ return initial_gdb_ttystate != NULL;
+}
+
/* Macro for printing errors from ioctl operations */
#define OOPSY(what) \
/* Set up a serial structure describing standard input. In inflow.c. */
extern void initialize_stdin_serial (void);
-extern int gdb_has_a_terminal (void);
-
extern void gdb_save_tty_state (void);
+/* Take a snapshot of our initial tty state before readline/ncurses
+ have had a chance to alter it. */
extern void set_initial_gdb_ttystate (void);
/* Set the process group of the caller to its own pid, or do nothing
+2016-08-23 Pedro Alves <palves@redhat.com>
+
+ PR gdb/20494
+ * gdb.base/new-ui-echo.c: New file.
+ * gdb.base/new-ui-echo.exp: New file.
+
2016-08-23 Yao Qi <yao.qi@linaro.org>
* gdb.server/connect-stopped-target.exp (do_test): Pass "" to
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2016 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+volatile int global = 0;
+
+int
+main (void)
+{
+ global = 1; /* set break main console here */
+ global = 1;
+ global = 1; /* set break extra console here */
+ global = 1;
+ return 0;
+}
--- /dev/null
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Regression test for PR 20494 (User input stops being echoed in CLI).
+# Before that bug was fixed, starting an inferior in a non-main UI
+# would result in GDB saving readline's prepped terminal state as
+# gdb's "own" terminal state (i.e., target_terminal_ours state),
+# resulting in subsequent synchronous execution commands in the main
+# UI disabling input echo.
+
+standard_testfile
+
+set compile_options "debug"
+if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} {
+ untested "failed to compile $testfile"
+ return -1
+}
+
+# Start gdb and create an extra console UI. Start the inferior in the
+# DRIVER console (either "main" or "extra"), and then enter a
+# synchronous execution command in the extra console. Before PR 20494
+# was fixed, if DRIVER was a secondary UI, GDB would lose input echo
+# on the main UI after the synchronous execution command. We test
+# with both main and extra UIs as driver consoles for completeness.
+
+proc echo_test {driver} {
+ global srcfile testfile
+ global gdb_prompt
+ global gdb_spawn_id
+ global gdb_main_spawn_id extra_spawn_id
+ global decimal
+
+ clean_restart $testfile
+
+ # Save the main UI's spawn ID.
+ set gdb_main_spawn_id $gdb_spawn_id
+
+ # Create the new PTY for the secondary console UI.
+ spawn -pty
+ set extra_spawn_id $spawn_id
+ set extra_tty_name $spawn_out(slave,name)
+ gdb_test_multiple "new-ui console $extra_tty_name" "new-ui" {
+ -re "New UI allocated\r\n$gdb_prompt $" {
+ }
+ }
+
+ with_spawn_id $extra_spawn_id {
+ set test "initial prompt on extra console"
+ gdb_test_multiple "" $test {
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+ }
+
+ set main_console [list $gdb_main_spawn_id "main console"]
+ set extra_console [list $extra_spawn_id "extra console"]
+
+ if {$driver == "main"} {
+ set con1 $main_console
+ set con2 $extra_console
+ } else {
+ set con1 $extra_console
+ set con2 $main_console
+ }
+
+ set con1_spawn_id [lindex $con1 0]
+ set con2_spawn_id [lindex $con2 0]
+ set con1_name [lindex $con1 1]
+ set con2_name [lindex $con2 1]
+
+ set bp_lineno [gdb_get_line_number "set break $con1_name here"]
+
+ with_spawn_id $con1_spawn_id {
+ gdb_test "break $srcfile:$bp_lineno" \
+ "Breakpoint $decimal .*$srcfile, line $bp_lineno\\." \
+ "set breakpoint using $con1_name"
+ gdb_run_cmd
+ gdb_test "" "set break $con1_name here .*" "run to breakpoint on $con1_name"
+ }
+
+ with_spawn_id $con2_spawn_id {
+ set test "breakpoint hit reported on $con2_name too"
+ gdb_test_multiple "" $test {
+ -re "Breakpoint $decimal, .* set break $con1_name here " {
+ pass $test
+ }
+ }
+ gdb_test "next" "global = 1;" "next on $con2_name"
+ }
+
+ # Ensure echo remains enabled in both consoles.
+ with_spawn_id $con1_spawn_id {
+ gdb_test "print 1" "^print 1\r\n\\\$1 = 1" "print on $con1_name echoes"
+ }
+ with_spawn_id $con2_spawn_id {
+ gdb_test "print 2" "^print 2\r\n\\\$2 = 2" "print on $con2_name echoes"
+ }
+}
+
+# The test driver.
+
+proc test_driver {} {
+
+ with_test_prefix "extra console as driver" {
+ echo_test "extra"
+ }
+
+ with_test_prefix "main console as driver" {
+ echo_test "main"
+ }
+
+}
+
+test_driver
if (interactive_mode == AUTO_BOOLEAN_AUTO)
fprintf_filtered (file, "Debugger's interactive mode "
"is %s (currently %s).\n",
- value, gdb_has_a_terminal () ? "on" : "off");
+ value, input_interactive_p (current_ui) ? "on" : "off");
else
fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value);
}