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