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/gdb-7.12-branch] Fix PR mi/20431 - Missing MI prompts after sync execution MI command (-exec-continue, etc.) errors


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

commit 4d38db46f6f6480ee33844164383ce40e5fc2440
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Aug 9 22:52:46 2016 +0100

    Fix PR mi/20431 - Missing MI prompts after sync execution MI command (-exec-continue, etc.) errors
    
    gdb 7.11 introduced an MI regression: a failing MI sync execution
    command misses printing the MI prompt, and then all subsequent command
    miss it too:
    
     $ gdb-7.11.1 -i=mi
     [...]
     p 1
     &"p 1\n"
     ~"$1 = 1"
     ~"\n"
     ^done
     (gdb)                                        <<< prompted ok
     -exec-continue
     ^error,msg="The program is not being run."   <<< missing prompt after this
     print 1
     &"print 1\n"
     ~"$2 = 1"
     ~"\n"
     ^done                                        <<< missing prompt after this
    
    
    gdb 7.10.1 behaved correctly, even with "set mi-async on":
    
     -exec-continue
     ^error,msg="The program is not being run."
     (gdb)                                        <<< prompted ok
    
    etc.
    
    Bisecting points at:
    
      commit 0b333c5e7d6c
      Author: Pedro Alves <palves@redhat.com>
      Date:   Wed Sep 9 18:23:23 2015 +0100
    
          Merge async and sync code paths some more
      [...]
    
    The problem is that when an exception is thrown, we leave the prompt
    state set to PROMPT_BLOCKED, and then mi_execute_command_input_handler
    doesn't print the prompt.  It used to work because before that patch,
    we happened to skip disabling stdin if the current target didn't do
    async (which it never does before execution).
    
    I was surprised to find that this bug isn't caught by the testsuite,
    so I made a thorough test that tests all combinations of pairs of:
    
     - a failing synchronous execution command
     - a failing non-execution command
     - a non-failing command
    
    gdb/ChangeLog:
    2016-08-09  Pedro Alves  <palves@redhat.com>
    
    	PR mi/20431
    	* mi/mi-main.c (mi_execute_command): Enable input and set prompt
    	state to PROMPT_NEEDED.
    
    gdb/testsuite/ChangeLog:
    2016-08-09  Pedro Alves  <palves@redhat.com>
    
    	PR mi/20431
    	* gdb.mi/mi-cmd-error.exp: New file.

Diff:
---
 gdb/ChangeLog                         |  6 +++
 gdb/mi/mi-main.c                      |  7 +++
 gdb/testsuite/ChangeLog               |  5 +++
 gdb/testsuite/gdb.mi/mi-cmd-error.exp | 80 +++++++++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b879ae0..53283b5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2016-08-09  Pedro Alves  <palves@redhat.com>
 
+	PR mi/20431
+	* mi/mi-main.c (mi_execute_command): Enable input and set prompt
+	state to PROMPT_NEEDED.
+
+2016-08-09  Pedro Alves  <palves@redhat.com>
+
 	PR gdb/18653
 	* Makefile.in (SFILES): Add
 	common/signals-state-save-restore.c.
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index b1cbd8b..1913157 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2139,6 +2139,13 @@ mi_execute_command (const char *cmd, int from_tty)
 	}
       CATCH (result, RETURN_MASK_ALL)
 	{
+	  /* Like in start_event_loop, enable input and force display
+	     of the prompt.  Otherwise, any command that calls
+	     async_disable_stdin, and then throws, will leave input
+	     disabled.  */
+	  async_enable_stdin ();
+	  current_ui->prompt_state = PROMPT_NEEDED;
+
 	  /* The command execution failed and error() was called
 	     somewhere.  */
 	  mi_print_exception (command->token, result);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6581556..605802f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2016-08-09  Pedro Alves  <palves@redhat.com>
 
+	PR mi/20431
+	* gdb.mi/mi-cmd-error.exp: New file.
+
+2016-08-09  Pedro Alves  <palves@redhat.com>
+
 	PR gdb/18653
 	* gdb.base/signals-state-child.c: New file.
 	* gdb.base/signals-state-child.exp: New file.
diff --git a/gdb/testsuite/gdb.mi/mi-cmd-error.exp b/gdb/testsuite/gdb.mi/mi-cmd-error.exp
new file mode 100644
index 0000000..a6d4791
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-cmd-error.exp
@@ -0,0 +1,80 @@
+# 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/>.
+
+# Test that after:
+#
+# - a failing synchronous execution command, or,
+# - a failing non-execution command, or,
+# - a non-failing command,
+#
+# ... MI continues processing input.  We actually test all
+# combinations of pairs of the above.  See PR mi/20431.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile
+
+# A synchronous execution execution command that errors out.
+
+proc failing_sync_execution_command {} {
+    mi_gdb_test "-exec-continue" \
+	{\^error,msg=\"The program is not being run.\"} \
+	"failing sync execution command"
+}
+
+# A non-execution command that errors out.
+
+proc failing_non_execution_command {} {
+    mi_gdb_test "-invalid-command" \
+	{\^error,msg=\"Undefined MI command: invalid-command\",code=\"undefined-command\"} \
+	"failing non-execution command"
+}
+
+# A command that doesn't error out.
+
+proc non_failing_command {} {
+    mi_gdb_test "-gdb-show version" \
+	".*Free Software Foundation.*\\^done" \
+	"non-failing command"
+}
+
+# A list of procedures to try.
+set procs {
+    failing_sync_execution_command
+    failing_non_execution_command
+    non_failing_command
+}
+
+# User-friendly names for procedures above, in the same order.
+set cmdnames {
+    "failing sync execution command"
+    "failing non-execution command"
+    "non-failing command"
+}
+
+for {set i 0} {$i < [llength $procs]} {incr i} {
+    for {set j 0} {$j < [llength $procs]} {incr j} {
+	with_test_prefix "[lindex $cmdnames $i] first ($i x $j)" {
+	    with_test_prefix "1st" [lindex $procs $i]
+	    with_test_prefix "2nd" [lindex $procs $j]
+	}
+    }
+}


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