1 # Copyright 2022-2024 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 # This test aims at testing various operations after getting rid of an inferior 17 # that was running in background, or while we have an inferior running in 18 # background. The original intent was to expose cases where the commit-resumed 19 # state of the process stratum target was not reset properly after killing an 20 # inferior running in background, which would be a problem when trying to run 21 # again. The test was expanded to test various combinations of 22 # run-control-related actions done with an inferior running in background. 23 24 require !use_gdb_stub 25 26 standard_testfile 27 28 if {[build_executable "failed to prepare" $testfile $srcfile]} { 29 return 30 } 31 32 # Run one variation of the test: 33 # 34 # 1. Start an inferior in the background with "run &" 35 # 2. Do action 1 36 # 3. Do action 2 37 # 38 # Action 1 indicates what to do with the inferior running in background: 39 # 40 # - kill: kill it 41 # - detach: detach it 42 # - add: add a new inferior and switch to it, leave the inferior running in 43 # background alone 44 # - none: do nothing, leave the inferior running in background alone 45 # 46 # Action 2 indicates what to do after that: 47 # 48 # - start: use the start command 49 # - run: use the run command 50 # - attach: start a process outside of GDB and attach it 51 proc do_test { action1 action2 } { 52 save_vars { ::GDBFLAGS } { 53 append ::GDBFLAGS " -ex \"maintenance set target-non-stop on\"" 54 clean_restart $::binfile 55 } 56 57 # Ensure we are at least after the getpid call, should we need it. 58 if { ![runto "after_getpid"] } { 59 return 60 } 61 62 # Some commands below ask for confirmation. Turn that off for simplicity. 63 gdb_test "set confirm off" 64 gdb_test -no-prompt-anchor "continue &" 65 66 if { $action1 == "kill" } { 67 gdb_test "kill" "Inferior 1 .* killed.*" 68 } elseif { $action1 == "detach" } { 69 set child_pid [get_integer_valueof "mypid" -1] 70 if { $child_pid == -1 } { 71 fail "failed to extract child pid" 72 return 73 } 74 75 gdb_test "detach" "Inferior 1 .* detached.*" "detach from first instance" 76 77 # Kill the detached process, to avoid hanging when exiting GDBserver, 78 # when testing with the native-extended-gdbserver board. 79 remote_exec target "kill $child_pid" 80 } elseif { $action1 == "add" } { 81 gdb_test "add-inferior -exec $::binfile" \ 82 "Added inferior 2 on connection 1.*" "add-inferior" 83 gdb_test "inferior 2" "Switching to inferior 2 .*" 84 } elseif { $action1 == "none" } { 85 86 } else { 87 error "invalid action 1" 88 } 89 90 if { $action2 == "start" } { 91 gdb_test "start" "Temporary breakpoint $::decimal\(?:\.$::decimal\)?, main .*" 92 } elseif { $action2 == "run" } { 93 gdb_test "break main" "Breakpoint $::decimal at $::hex.*" 94 gdb_test "run" "Breakpoint $::decimal\(?:\.$::decimal\)?, main .*" 95 } elseif { $action2 == "attach" } { 96 set test_spawn_id [spawn_wait_for_attach $::binfile] 97 set test_pid [spawn_id_get_pid $test_spawn_id] 98 99 if { [gdb_attach $test_pid] } { 100 gdb_test "detach" "Inferior $::decimal .* detached.*" \ 101 "detach from second instance" 102 } 103 104 # Detach and kill this inferior so we don't leave it around. 105 kill_wait_spawned_process $test_spawn_id 106 } else { 107 error "invalid action 2" 108 } 109 } 110 111 foreach_with_prefix action1 { kill detach add none } { 112 foreach_with_prefix action2 { start run attach } { 113 if { $action2 == "attach" && ![can_spawn_for_attach] } { 114 continue 115 } 116 do_test $action1 $action2 117 } 118 } 119