xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.base/batch-preserve-term-settings.exp (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
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