| # Copyright 2016-2021 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 that -exec-run works as expected. Exercises various testing |
| # axes: |
| # |
| # - MI running on main UI vs separate UI. |
| # |
| # - inferior tty set to main tty vs separate tty. |
| # |
| # - forking the child failing and sending output to the right inferior |
| # terminal, vs the child not failing to start. |
| |
| load_lib mi-support.exp |
| set MIFLAGS "-i=mi" |
| |
| # The purpose of this testcase is to test the -exec-run command. If we |
| # cannot use it, then there is no point in running this testcase. |
| if [use_gdb_stub] { |
| untested "cannot use -exec-run command" |
| return -1 |
| } |
| |
| standard_testfile mi-start.c |
| |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { |
| untested "could not build mi-exec-run" |
| return -1 |
| } |
| |
| # The test proper. INFTTY_MODE determines whether "set inferior-tty" |
| # is in effect. MI_MODE determines whether MI is run on the main UI, |
| # or as a separate UI. FORCE_FAIL is true when we want -exec-run to |
| # fail and cause inferior output be sent to the inferior tty. |
| |
| proc test {inftty_mode mi_mode force_fail} { |
| global srcdir subdir binfile srcfile |
| global gdb_spawn_id gdb_main_spawn_id mi_spawn_id inferior_spawn_id |
| global decimal |
| |
| mi_gdb_exit |
| |
| set start_ops {} |
| if {$inftty_mode == "separate"} { |
| lappend start_ops "separate-inferior-tty" |
| } |
| if {$mi_mode == "separate"} { |
| lappend start_ops "separate-mi-tty" |
| } |
| |
| if [eval mi_gdb_start $start_ops] { |
| return |
| } |
| |
| if {$force_fail} { |
| # Disable the shell so that its the first exec that fails, |
| # instead of the shell starting and then failing with some |
| # unspecified output. |
| mi_gdb_test "-gdb-set startup-with-shell off" ".*" |
| set bin $binfile.nox |
| } else { |
| set bin $binfile |
| } |
| |
| mi_delete_breakpoints |
| mi_gdb_reinitialize_dir $srcdir/$subdir |
| mi_gdb_reinitialize_dir $srcdir/$subdir |
| mi_gdb_load ${bin} |
| |
| # Useful for debugging: |
| verbose -log "Channels:" |
| verbose -log " inferior_spawn_id=$inferior_spawn_id" |
| verbose -log " gdb_spawn_id=$gdb_spawn_id" |
| verbose -log " gdb_main_spawn_id=$gdb_main_spawn_id" |
| verbose -log " mi_spawn_id=$mi_spawn_id" |
| |
| if {$force_fail} { |
| set saw_perm_error 0 |
| set saw_mi_error 0 |
| set test "run failure detected" |
| send_gdb "-exec-run --start\n" |
| |
| while {1} { |
| gdb_expect { |
| -i "$inferior_spawn_id" |
| -re ".*Cannot exec.*Permission denied" { |
| set saw_perm_error 1 |
| verbose -log "saw mi error" |
| } |
| -i "$gdb_spawn_id" |
| -re "\\^error,msg=\"During startup program exited with code 127" { |
| set saw_mi_error 1 |
| verbose -log "saw mi error" |
| } |
| timeout { |
| fail "$test (timeout)" |
| break |
| } |
| -i "$gdb_main_spawn_id" |
| eof { |
| fail "$test (eof)" |
| break |
| } |
| } |
| |
| if {$saw_perm_error && $saw_mi_error} { |
| pass $test |
| break |
| } |
| } |
| } else { |
| mi_run_cmd "--start" |
| mi_expect_stop "breakpoint-hit" "main" "" ".*$srcfile" "$decimal" \ |
| { "" "disp=\"del\"" } "breakpoint hit reported on mi" |
| |
| if {$mi_mode == "separate"} { |
| # Check that the breakpoint hit is reported on the main |
| # UI/CLI. Note no prompt is expected. |
| switch_gdb_spawn_id $gdb_main_spawn_id |
| |
| set test "breakpoint hit reported on console" |
| gdb_test_multiple "" $test { |
| -re "Temporary breakpoint .*, main \\(\\) at .*$srcfile:$decimal.*return 0;" { |
| pass $test |
| } |
| } |
| |
| # Switch back to the MI UI. |
| global mi_spawn_id |
| switch_gdb_spawn_id $mi_spawn_id |
| } |
| } |
| } |
| |
| # Create a not-executable copy of the program, in order to exercise |
| # vfork->exec failing. |
| gdb_remote_download host $binfile $binfile.nox |
| remote_spawn target "chmod \"a-x\" $binfile.nox" |
| |
| foreach_with_prefix inferior-tty {"main" "separate"} { |
| foreach_with_prefix mi {"main" "separate"} { |
| foreach_with_prefix force-fail {0 1} { |
| test ${inferior-tty} ${mi} ${force-fail} |
| } |
| } |
| } |