diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/new-ui-pending-input.c | 26 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/new-ui-pending-input.exp | 123 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 22 | ||||
-rw-r--r-- | gdb/top.c | 11 |
6 files changed, 194 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e5e0cb5..108528d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2016-09-06 Pedro Alves <palves@redhat.com> + * top.c (wait_sync_command_done): Don't assume current_ui doesn't + change across events. Restore the current UI before returning. + (gdb_readline_wrapper): Restore the current UI before returning. + +2016-09-06 Pedro Alves <palves@redhat.com> + * event-top.c (restore_ui_cleanup): Now static. (make_cleanup_restore_current_ui): New function. (switch_thru_all_uis_init): Use it. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 16070a3..958ec27 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2016-09-06 Pedro Alves <palves@redhat.com> + + * gdb.base/new-ui-pending-input.c: New file. + * gdb.base/new-ui-pending-input.exp: New file. + * gdb.exp (clear_gdb_spawn_id): New procedure. + (with_spawn_id): Check whether gdb_spawn_id exists before + referencing it. If gdb_spawn_id didn't exist on entry, clear it + on exit. + 2016-09-05 Ulrich Weigand <uweigand@de.ibm.com> * gdb.base/float128.c: New file. diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.c b/gdb/testsuite/gdb.base/new-ui-pending-input.c new file mode 100644 index 0000000..a4bae7d --- /dev/null +++ b/gdb/testsuite/gdb.base/new-ui-pending-input.c @@ -0,0 +1,26 @@ +/* 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/>. +*/ + +#include <unistd.h> + +int +main (void) +{ + sleep (2); + return 0; /* set breakpoint here */ +} diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb.base/new-ui-pending-input.exp new file mode 100644 index 0000000..325c30f --- /dev/null +++ b/gdb/testsuite/gdb.base/new-ui-pending-input.exp @@ -0,0 +1,123 @@ +# 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 'gdb "-ex new-ui TTY" -ex "start"' (or any other synchronous +# execution command), when TTY already has input pending. GDB used to +# internal error in this situation. + +standard_testfile + +set compile_options "debug" +if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} { + untested "failed to compile $testfile" + return -1 +} + +# See intro. + +proc test_command_line_new_ui_pending_input {} { + global gdb_prompt + global binfile + + # This test requires running a synchronous execution command from + # the command line. + if {[use_gdb_stub] || [target_info gdb_protocol] == "extended-remote" } { + unsupported "can't run from the command line" + return 0 + } + + spawn -pty + set extra_spawn_id $spawn_id + set extra_tty_name $spawn_out(slave,name) + + # An arbitrary number of prints. + set nprints 3 + + # Queue a few commands before GDB is started. + with_spawn_id $extra_spawn_id { + for {set i 1} {$i <= $nprints} {incr i} { + send_gdb "print $i\n" + } + } + pass "commands pending" + + # Now spawn GDB, creating a new-ui and at the same time running a + # synchronous command. + set test "spawn gdb" + + set bpline [gdb_get_line_number "set breakpoint here"] + + set options "" + append options " -iex \"set height 0\"" + append options " -iex \"set width 0\"" + append options " -iex \"new-ui console $extra_tty_name\"" + append options " -ex \"b $bpline\"" + append options " -ex \"run\"" + + if {[gdb_spawn_with_cmdline_opts "$options $binfile"] != 0} { + fail $test + return + } else { + pass $test + } + + # Consume the initial prompt on the extra console. + with_spawn_id $extra_spawn_id { + set test "initial prompt on extra console" + gdb_test_multiple "" $test { + -re "$gdb_prompt $" { + pass $test + } + } + } + + # Check that we see the result of the print commands in the extra + # UI. + with_spawn_id $extra_spawn_id { + for {set i 1} {$i <= $nprints} {incr i} { + set test "print $i on extra console" + gdb_test_multiple "" $test { + -re " = $i\r\n$gdb_prompt " { + pass "$test" + } + } + } + } + + # Now check that we reach the breakpoint successfully. + set test "run to breakpoint on main console" + gdb_test_multiple "" $test { + -re "Breakpoint .* main .*set breakpoint here.*$gdb_prompt $" { + pass $test + } + } + + # And likewise on the extra console. No prompt is expected. + with_spawn_id $extra_spawn_id { + set test "run to breakpoint on extra console" + gdb_test_multiple "" $test { + -re "Breakpoint .* main .*set breakpoint here" { + pass $test + } + } + } +} + +# The driver. Calls all tests. +proc testcase_driver {} { + test_command_line_new_ui_pending_input +} + +testcase_driver diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 5cab774..e538812 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -2087,17 +2087,35 @@ proc switch_gdb_spawn_id {spawn_id} { set board_info($board,fileid) $spawn_id } +# Clear the default spawn id. + +proc clear_gdb_spawn_id {} { + global gdb_spawn_id + global board board_info + + unset -nocomplain gdb_spawn_id + set board [host_info name] + unset -nocomplain board_info($board,fileid) +} + # Run BODY with SPAWN_ID as current spawn id. proc with_spawn_id { spawn_id body } { global gdb_spawn_id - set saved_spawn_id $gdb_spawn_id + if [info exists gdb_spawn_id] { + set saved_spawn_id $gdb_spawn_id + } + switch_gdb_spawn_id $spawn_id set code [catch {uplevel 1 $body} result] - switch_gdb_spawn_id $saved_spawn_id + if [info exists saved_spawn_id] { + switch_gdb_spawn_id $saved_spawn_id + } else { + clear_gdb_spawn_id + } if {$code == 1} { global errorInfo errorCode @@ -561,9 +561,15 @@ check_frame_language_change (void) void wait_sync_command_done (void) { + /* Processing events may change the current UI. */ + struct cleanup *old_chain = make_cleanup_restore_current_ui (); + struct ui *ui = current_ui; + while (gdb_do_one_event () >= 0) - if (current_ui->prompt_state != PROMPT_BLOCKED) + if (ui->prompt_state != PROMPT_BLOCKED) break; + + do_cleanups (old_chain); } /* See top.h. */ @@ -1030,6 +1036,9 @@ gdb_readline_wrapper (const char *prompt) ui->secondary_prompt_depth++; back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup); + /* Processing events may change the current UI. */ + make_cleanup_restore_current_ui (); + if (cleanup->target_is_async_orig) target_async (0); |