1# Copyright 1997-2019 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 is a test of gdb's follow-exec-mode. 17# 18# It first checks that exec events are supported by using a catchpoint, 19# then tests multiple scenarios for follow-exec-mode using parameters 20# that test: 21# - each mode 22# - different commands to execute past the exec 23# - re-running both the original and new inferiors. 24# 25# Note that we can't single-step past an exec call. There has to 26# be a breakpoint in order to stop after the exec, even if we use 27# a single-step command to execute past the exec. 28 29# Remote mode doesn't support the 'run' command, which is 30# required for follow-exec-mode testing. 31if { [target_info exists gdb_protocol] 32 && [target_info gdb_protocol] == "remote" } { 33 continue 34} 35 36# Until "catch exec" is implemented on other targets... 37# 38if {![istarget "*-linux*"]} then { 39 continue 40} 41 42standard_testfile foll-exec-mode.c 43 44set testfile2 "execd-prog" 45set srcfile2 ${testfile2}.c 46set binfile2 [standard_output_file ${testfile2}] 47 48set compile_options debug 49 50# build the first test case 51if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } { 52 untested "failed to compile" 53 return -1 54} 55 56if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } { 57 untested "failed to compile" 58 return -1 59} 60 61# Test exec catchpoints to ensure exec events are supported. 62# 63proc do_catch_exec_test { } { 64 global testfile 65 global gdb_prompt 66 67 clean_restart $testfile 68 69 # Start the program running, and stop at main. 70 # 71 if ![runto_main] then { 72 fail "couldn't run ${testfile}" 73 return 74 } 75 76 # Verify that the system supports "catch exec". 77 gdb_test "catch exec" "Catchpoint \[0-9\]* \\(exec\\)" "insert first exec catchpoint" 78 set has_exec_catchpoints 0 79 gdb_test_multiple "continue" "continue to first exec catchpoint" { 80 -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" { 81 unsupported "continue to first exec catchpoint" 82 } 83 -re ".*Catchpoint.*$gdb_prompt $" { 84 set has_exec_catchpoints 1 85 pass "continue to first exec catchpoint" 86 } 87 } 88 89 if {$has_exec_catchpoints == 0} { 90 unsupported "exec catchpoints" 91 return 92 } 93} 94 95# Test follow-exec-mode in the specified scenario. 96# MODE determines whether follow-exec-mode is "same" or "new". 97# CMD determines the command used to execute past the exec call. 98# INFSWITCH is ignored for MODE == "same", and for "new" it is 99# used to determine whether to switch to the original inferior 100# before re-running. 101 102proc do_follow_exec_mode_tests { mode cmd infswitch } { 103 global binfile srcfile srcfile2 testfile testfile2 104 global gdb_prompt 105 106 with_test_prefix "$mode,$cmd,$infswitch" { 107 clean_restart $testfile 108 109 # Start the program running, and stop at main. 110 # 111 if ![runto_main] then { 112 fail "couldn't run ${testfile}" 113 return 114 } 115 116 # Set the follow-exec mode. 117 # 118 gdb_test_no_output "set follow-exec-mode $mode" 119 120 # Run to the line of the exec call. 121 # 122 gdb_breakpoint [gdb_get_line_number "Set breakpoint here"] 123 gdb_continue_to_breakpoint "continue to line of exec call" 124 125 # Set up the output we expect to see after we execute past the exec. 126 # 127 set execd_line [gdb_get_line_number "after-exec" $srcfile2] 128 set expected_re ".*xecuting new program: .*${testfile2}.*Breakpoint .,.*${srcfile2}:${execd_line}.*$gdb_prompt $" 129 130 # Set a breakpoint after the exec call if we aren't single-stepping 131 # past it. 132 # 133 if {$cmd == "continue"} { 134 gdb_breakpoint "$execd_line" 135 } 136 137 # Execute past the exec call. 138 # 139 set test "$cmd past exec" 140 gdb_test_multiple $cmd $test { 141 -re "$expected_re" { 142 pass $test 143 } 144 } 145 146 # Set expected output, given the test parameters. 147 # 148 if {$mode == "same"} { 149 set expected_re "\\* 1.*process.*" 150 } else { 151 set expected_re " 1.*null.*$testfile.*\r\n\\* 2.*process.*$testfile2 .*" 152 } 153 154 # Check that the inferior list is correct: 155 # - one inferior for MODE == "same" 156 # - two inferiors for MODE == "new", current is execd program 157 # 158 gdb_test "info inferiors" $expected_re "Check inferior list" 159 160 set expected_inf "" 161 if {$mode == "same"} { 162 # One inferior, the execd program. 163 set expected_inf $testfile2 164 } elseif {$infswitch == "infswitch"} { 165 # Two inferiors, we have switched to the original program. 166 set expected_inf $testfile 167 gdb_test "inferior 1" "Switching to inferior 1.*$testfile.*" "switch inferiors" 168 } else { 169 # Two inferiors, run the execd program 170 set expected_inf $testfile2 171 } 172 173 # Now check that a 'run' command will run the correct inferior. 174 # 175 set test "use correct executable ($expected_inf) for run after follow exec" 176 gdb_run_cmd 177 gdb_test_multiple "" $test { 178 -re {Start it from the beginning\? \(y or n\) $} { 179 send_gdb "y\n" 180 exp_continue 181 } 182 -re "Starting program: .*$expected_inf.*Breakpoint .,.*\r\n$gdb_prompt $" { 183 pass $test 184 } 185 } 186 } 187} 188 189do_catch_exec_test 190 191foreach cmd {"next" "continue"} { 192 foreach mode {"same" "new"} { 193 # Test basic follow-exec-mode. 194 do_follow_exec_mode_tests $mode $cmd "no_infswitch" 195 if {$mode == "new"} { 196 # Test that when we do 'run' we get the correct executable. 197 do_follow_exec_mode_tests $mode $cmd "infswitch" 198 } 199 } 200} 201 202return 0 203