1# Copyright (C) 2015-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# Check that "gdb -batch -ex run" does not leave the terminal in the 17# wrong state. 18 19standard_testfile 20 21if {[build_executable "failed to prepare" $testfile $srcfile debug] == -1} { 22 return -1 23} 24 25set file_arg $binfile 26if [is_remote host] { 27 set file_arg [remote_download host $file_arg] 28} 29 30# The shell's prompt. 31set shell_prompt_ps1 "gdb-subshell$ " 32set shell_prompt_re [string_to_regexp $shell_prompt_ps1] 33 34# Spawn shell. Returns true on success, false otherwise. 35 36proc spawn_shell {} { 37 global shell_prompt_ps1 shell_prompt_re 38 39 set res [remote_spawn host "/bin/sh"] 40 if { $res < 0 || $res == "" } { 41 unsupported "spawning shell failed." 42 return 0 43 } 44 45 send_gdb "PS1=\"$shell_prompt_ps1\"\n" 46 47 # Try to match: 48 # PS1="gdb-subshell$ "^M 49 # $ gdb-subshell$ 50 # or: 51 # PS1="gdb-subshell$ "^M 52 # sh-4.4$ PS1="gdb-subshell$ "^M 53 # gdb-subshell$ 54 set gotit 0 55 set test "spawn shell" 56 gdb_expect { 57 -re "PS1=\"$shell_prompt_re" { 58 exp_continue 59 } 60 -re "$shell_prompt_re$" { 61 pass $test 62 set gotit 1 63 } 64 timeout { 65 fail "$test (timeout)" 66 } 67 eof { 68 fail "$test (eof)" 69 } 70 } 71 72 return $gotit 73} 74 75# Exit the shell. 76 77proc exit_shell {} { 78 global shell_prompt_re 79 80 set test "exit shell" 81 send_gdb "exit\n" 82 gdb_expect { 83 timeout { 84 fail "$test (timeout)" 85 return 0 86 } 87 eof { 88 pass "$test" 89 } 90 } 91 if ![is_remote host] { 92 remote_close host 93 } 94} 95 96# Run "stty" and store the output in $result. Returns true on 97# success, false otherwise. 98 99proc run_stty {message result} { 100 global shell_prompt_re 101 102 upvar $result output 103 104 send_gdb "stty || echo \"not found\"\n" 105 set gotit 0 106 gdb_expect { 107 -re "not found.*not found.*$shell_prompt_re$" { 108 pass "$message (not found)" 109 } 110 -re "(.*)$shell_prompt_re$" { 111 set output $expect_out(1,string) 112 set gotit 1 113 pass $message 114 } 115 timeout { 116 fail "$message (timeout)" 117 } 118 eof { 119 fail "$message (eof)" 120 } 121 } 122 return $gotit 123} 124 125# Check that "gdb -batch -ex run" does not leave the terminal in the 126# wrong state. 127 128proc test_terminal_settings_preserved {} { 129 global file_arg 130 global GDB INTERNAL_GDBFLAGS GDBFLAGS 131 global gdb_prompt 132 global shell_prompt_re 133 134 if ![spawn_shell] { 135 return 136 } 137 138 set stty_supported [run_stty "stty before" stty_before] 139 140 set test "gdb -batch -ex run" 141 append EXTRA_GDBFLAGS "-batch" 142 append EXTRA_GDBFLAGS " -ex \"set height unlimited\"" 143 append EXTRA_GDBFLAGS " -ex \"start\"" 144 append EXTRA_GDBFLAGS " --args \"$file_arg\"" 145 send_gdb "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS $EXTRA_GDBFLAGS [host_info gdb_opts]\n" 146 gdb_expect { 147 -re "Don't know how to run.*$shell_prompt_re$" { 148 unsupported $test 149 } 150 -re "$gdb_prompt $" { 151 # -batch implies no GDB prompt. 152 fail $test 153 } 154 -re "Temporary breakpoint .*$shell_prompt_re$" { 155 pass $test 156 } 157 timeout { 158 fail "$test (timeout)" 159 } 160 eof { 161 fail "$test (eof)" 162 } 163 } 164 165 set test "echo test_echo" 166 send_gdb "echo test_echo\n" 167 gdb_expect { 168 -re "^echo test_echo\r\ntest_echo\r\n.*$shell_prompt_re$" { 169 pass $test 170 } 171 timeout { 172 fail "$test (timeout)" 173 } 174 eof { 175 fail "$test (eof)" 176 } 177 } 178 179 set test "terminal settings preserved" 180 if $stty_supported { 181 run_stty "stty after" stty_after 182 183 gdb_assert [string equal $stty_before $stty_after] $test 184 } else { 185 unsupported "$test (no stty)" 186 } 187 188 exit_shell 189} 190 191# Send the quit command to GDB and make sure it exits. 192 193proc send_quit_command { test_name } { 194 global shell_prompt_re 195 196 set test $test_name 197 send_gdb "quit\n" 198 gdb_expect { 199 -re "(y or n)" { 200 send_gdb "y\n" 201 exp_continue 202 } 203 -re ".*$shell_prompt_re$" { 204 pass $test 205 return 206 } 207 timeout { 208 fail "$test (timeout)" 209 return 0 210 } 211 eof { 212 fail "$test (eof)" 213 return 0 214 } 215 } 216} 217 218# Check that quitting from the CLI via the "quit" command does not leave the 219# terminal in the wrong state. The GDB commands CMDS are executed before 220# quitting. 221 222proc test_terminal_settings_preserved_after_cli_exit { cmds } { 223 global file_arg 224 global GDB INTERNAL_GDBFLAGS GDBFLAGS 225 global gdb_prompt 226 global shell_prompt_re 227 228 if ![spawn_shell] { 229 return 230 } 231 232 set saved_gdbflags $GDBFLAGS 233 234 set stty_supported [run_stty "stty before" stty_before] 235 236 set test "start gdb" 237 send_gdb "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts] --args \"$file_arg\"\n" 238 gdb_expect { 239 -re "$gdb_prompt $" { 240 pass $test 241 } 242 timeout { 243 fail "$test (timeout)" 244 } 245 eof { 246 fail "$test (eof)" 247 } 248 } 249 250 foreach cmd $cmds { 251 set test "run command $cmd" 252 send_gdb "$cmd\n" 253 gdb_expect { 254 -re "$gdb_prompt $" { 255 pass $test 256 } 257 timeout { 258 fail "$test (timeout)" 259 } 260 eof { 261 fail "$test (eof)" 262 } 263 } 264 } 265 266 send_quit_command "quit gdb" 267 268 set test "terminal settings preserved" 269 if $stty_supported { 270 run_stty "stty after" stty_after 271 272 gdb_assert [string equal $stty_before $stty_after] $test 273 } else { 274 unsupported "$test (no stty)" 275 } 276 277 exit_shell 278} 279 280# Check that sending SIGTERM kills GDB and does not leave the terminal in the 281# wrong state. 282 283proc test_terminal_settings_preserved_after_sigterm { } { 284 global file_arg 285 global GDB INTERNAL_GDBFLAGS GDBFLAGS 286 global gdb_prompt 287 global shell_prompt_re 288 289 # On Windows, GDB's "shell" command spawns cmd.exe, which does not 290 # understand PPID. So we're out of luck even if the test harness 291 # uses a remote_exec shell with a working "kill" command. 292 if [ishost *-*-mingw*] { 293 return 294 } 295 296 if ![spawn_shell] { 297 return 298 } 299 300 set saved_gdbflags $GDBFLAGS 301 302 set stty_supported [run_stty "stty before" stty_before] 303 304 set test "start gdb" 305 send_gdb "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]\n" 306 gdb_expect { 307 -re "$gdb_prompt $" { 308 pass $test 309 } 310 timeout { 311 fail "$test (timeout)" 312 } 313 eof { 314 fail "$test (eof)" 315 } 316 } 317 318 # Retrieve the pid of gdb with the gdb command "shell echo $PPID" 319 set gdb_pid -1 320 set test "run shell echo \$PPID" 321 send_gdb "shell echo \$PPID\n" 322 gdb_expect { 323 -re ".*\r\n(\\d+)\r\n$gdb_prompt $" { 324 set gdb_pid $expect_out(1,string) 325 pass $test 326 } 327 -re ".*\r\n\r\n$gdb_prompt $" { 328 fail "$test (no \$PPID)" 329 } 330 timeout { 331 fail "$test (timeout)" 332 } 333 eof { 334 fail "$test (eof)" 335 } 336 } 337 338 set test "kill gdb with SIGTERM" 339 if { $gdb_pid == -1 } { 340 fail "$test (no pid)" 341 send_quit_command "quit gdb" 342 } else { 343 remote_exec host "kill -TERM $gdb_pid" 344 set gdb_killed 0 345 gdb_expect { 346 -re ".*$shell_prompt_re$" { 347 pass $test 348 set gdb_killed 1 349 } 350 default { 351 fail "$test (did not quit)" 352 } 353 } 354 355 if !$gdb_killed { 356 send_quit_command "quit gdb" 357 } 358 } 359 360 set test "terminal settings preserved" 361 if $stty_supported { 362 run_stty "stty after" stty_after 363 364 gdb_assert [string equal $stty_before $stty_after] $test 365 } else { 366 unsupported "$test (no stty)" 367 } 368 369 exit_shell 370} 371 372with_test_prefix "batch run" { 373 test_terminal_settings_preserved 374} 375 376with_test_prefix "cli exit" { 377 test_terminal_settings_preserved_after_cli_exit { } 378} 379 380with_test_prefix "cli exit after start cmd" { 381 test_terminal_settings_preserved_after_cli_exit { "start" } 382} 383 384with_test_prefix "cli exit after run cmd" { 385 test_terminal_settings_preserved_after_cli_exit { "run" } 386} 387 388with_test_prefix "cli exit after SIGTERM" { 389 test_terminal_settings_preserved_after_sigterm 390} 391