1 # This testcase is part of GDB, the GNU debugger. 2 # 3 # Copyright 2019-2024 Free Software Foundation, Inc. 4 # 5 # This program is free software; you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation; either version 3 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 # Test what happens if we have multiple UIs in use, and an error 19 # occurs while running a GDB command. Specifically, do both UIs 20 # return to an interactive state, or does one (or both) of them get 21 # stuck in a non-interactive state. 22 23 load_lib gdbserver-support.exp 24 25 standard_testfile 26 27 require allow_gdbserver_tests 28 # The test-case uses "spawn -pty", which creates a pty on build, which gdb 29 # cannot use on remote host. 30 require {!is_remote host} 31 32 save_vars { GDBFLAGS } { 33 # If GDB and GDBserver are both running locally, set the sysroot to avoid 34 # reading files via the remote protocol. 35 if { ![is_remote host] && ![is_remote target] } { 36 set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" 37 } 38 39 if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { 40 return -1 41 } 42 } 43 44 # Make sure we're disconnected, in case we're testing with an 45 # extended-remote board, therefore already connected. 46 gdb_test "disconnect" ".*" 47 48 # Start gdbserver. 49 set res [gdbserver_spawn "${binfile}"] 50 set gdbserver_protocol [lindex $res 0] 51 set gdbserver_gdbport [lindex $res 1] 52 set gdbserver_pid [exp_pid -i $server_spawn_id] 53 54 # Save the main UI's spawn ID. 55 set gdb_main_spawn_id $gdb_spawn_id 56 57 # Create the new PTY for the secondary console UI, issue the 'new-ui' 58 # command, and wait for a prompt on the second UI. 59 spawn -pty 60 set extra_spawn_id $spawn_id 61 set extra_tty_name $spawn_out(slave,name) 62 gdb_test_multiple "new-ui console $extra_tty_name" "new-ui" { 63 -re "New UI allocated\r\n$gdb_prompt $" { 64 pass $gdb_test_name 65 } 66 } 67 with_spawn_id $extra_spawn_id { 68 gdb_test_multiple "" "initial prompt on extra console" { 69 -re "$gdb_prompt $" { 70 pass $gdb_test_name 71 } 72 } 73 } 74 75 # Connect to the remote and continue its execution from the other UI. 76 with_spawn_id $extra_spawn_id { 77 gdb_test "target $gdbserver_protocol $gdbserver_gdbport" ".*" \ 78 "connect to gdbserver" 79 80 # Issue a continue and consume the response. Don't expect a prompt. 81 gdb_test_multiple "continue" "continue - extra UI" { 82 -re "\r\nContinuing\.\r\n" { 83 pass $gdb_test_name 84 } 85 } 86 } 87 88 # We're going to kill the gdbserver, but before we do, lets make sure 89 # that the inferior has started executing. 90 with_spawn_id $server_spawn_id { 91 gdb_test_multiple "" "ensure inferior is running" { 92 -re "@@XX@@ Inferior Starting @@XX@@" { 93 pass $gdb_test_name 94 } 95 timeout { 96 fail $gdb_test_name 97 } 98 } 99 } 100 101 # Interact with the main UI. 102 with_spawn_id $gdb_main_spawn_id { 103 gdb_test "echo hello\\n" "hello" "interact with GDB's main UI" 104 } 105 106 # Get the gdbserver PID. 107 set gdbserver_pid 0 108 with_spawn_id $gdb_main_spawn_id { 109 gdb_test -no-prompt-anchor "interrupt" 110 111 gdb_test_multiple "" "interrupt arrived" { 112 -re "Program received signal SIGINT, Interrupt\\.\r\n" { 113 pass $gdb_test_name 114 } 115 } 116 117 gdb_test_multiple "p server_pid" "" { 118 -re -wrap " = ($decimal)" { 119 set gdbserver_pid $expect_out(1,string) 120 pass $gdb_test_name 121 } 122 } 123 124 gdb_test_multiple continue "" { 125 -re "Continuing\\.\r\n" { 126 pass $gdb_test_name 127 } 128 } 129 } 130 131 if { $gdbserver_pid == 0 } { 132 return 133 } 134 135 # Now kill the gdbserver. 136 remote_exec target "kill -9 $gdbserver_pid" 137 138 # We expect to land back at a GDB prompt in both UIs, however there is 139 # currently an issue that in the original UI GDB doesn't reprint its 140 # prompt. That said, getting a prompt isn't the point of this test. 141 # The point is that we should be able to interact with GDB from either 142 # interpreter now. 143 144 with_spawn_id $gdb_main_spawn_id { 145 gdb_test_multiple "" "remote connection closed - main UI" { 146 -re -wrap "Remote connection closed" { 147 pass $gdb_test_name 148 } 149 } 150 } 151 152 with_spawn_id $gdb_main_spawn_id { 153 gdb_test "echo" "" \ 154 "main UI, prompt after gdbserver dies" 155 } 156 157 with_spawn_id $extra_spawn_id { 158 gdb_test "echo" "" \ 159 "extra UI, prompt after gdbserver dies" 160 } 161