1# Copyright 1997, 1999 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 2 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, write to the Free Software 15# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 17# Please email any bugs, comments, and/or additions to this file to: 18# bug-gdb@prep.ai.mit.edu 19 20if $tracelevel then { 21 strace $tracelevel 22 } 23 24if { ![isnative] } then { 25 continue 26} 27 28set prms_id 0 29set bug_id 0 30 31set testfile "foll-exec" 32set testfile2 "execd-prog" 33set srcfile ${testfile}.c 34set srcfile2 ${testfile2}.c 35set binfile ${objdir}/${subdir}/${testfile} 36set binfile2 ${objdir}/${subdir}/${testfile2} 37 38# build the first test case 39if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } { 40 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 41} 42 43if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 44 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 45} 46 47 48# Until "catch exec" is implemented on other targets... 49# 50if ![istarget "hppa*-hp-hpux*"] then { 51 continue 52} 53 54proc zap_session {} { 55 global gdb_prompt 56 global binfile 57 58 send_gdb "kill\n" 59 gdb_expect { 60 -re ".*Kill the program being debugged.*y or n. $" { 61 send_gdb "y\n" 62 send_gdb "file $binfile\n" 63 gdb_expect { 64 -re ".*Load new symbol table from.*y or n. $" { 65 send_gdb "y\n" 66 gdb_expect { 67 -re "Reading symbols from.*$gdb_prompt $" {} 68 timeout { fail "loading symbols (timeout)"; return } 69 } 70 } 71 -re ".*gdb_prompt $" {} 72 timeout { fail "loading symbols (timeout)"; return } 73 } 74 } 75 -re ".*$gdb_prompt $" {} 76 timeout { fail "killing inferior (timeout)" ; return } 77 } 78} 79 80proc do_exec_tests {} { 81 global gdb_prompt 82 global binfile 83 global srcfile 84 global srcfile2 85 global testfile 86 global testfile2 87 88 # Start the program running, and stop at main. 89 # 90 if ![runto_main] then { 91 perror "Couldn't run ${testfile}" 92 return 93 } 94 95 # Verify that we can see various global and local variables 96 # in this program, and that they have expected values. Some 97 # of these variables are also declared in the program we'll 98 # exec in a moment. 99 # 100 send_gdb "next 3\n" 101 gdb_expect { 102 -re "20.*execlp.*$gdb_prompt $"\ 103 {pass "step to exec call"} 104 -re "$gdb_prompt $" {fail "step to exec call"} 105 timeout {fail "(timeout) step to exec call"} 106 } 107 send_gdb "print global_i\n" 108 gdb_expect { 109 -re ".* = 100.*$gdb_prompt $"\ 110 {pass "print follow-exec/global_i"} 111 -re "$gdb_prompt $" {fail "print follow-exec/global_i"} 112 timeout {fail "(timeout) print follow-exec/global_i"} 113 } 114 send_gdb "print local_j\n" 115 gdb_expect { 116 -re ".* = 101.*$gdb_prompt $"\ 117 {pass "print follow-exec/local_j"} 118 -re "$gdb_prompt $" {fail "print follow-exec/local_j"} 119 timeout {fail "(timeout) print follow-exec/local_j"} 120 } 121 send_gdb "print local_k\n" 122 gdb_expect { 123 -re ".* = 102.*$gdb_prompt $"\ 124 {pass "print follow-exec/local_k"} 125 -re "$gdb_prompt $" {fail "print follow-exec/local_k"} 126 timeout {fail "(timeout) print follow-exec/local_k"} 127 } 128 129 # Try stepping through an execlp call, without catching it. 130 # We should stop in execd-program, at its first statement. 131 # 132 send_gdb "next\n" 133 gdb_expect { 134 -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\ 135 {pass "step through execlp call"} 136 -re "$gdb_prompt $" {fail "step through execlp call"} 137 timeout {fail "(timeout) step through execlp call"} 138 } 139 140 # Verify that we can see the variables defined in the newly-exec'd 141 # program, and CANNOT see those defined in the exec'ing program. 142 # 143 send_gdb "next\n" 144 gdb_expect { 145 -re "26.*printf.*$gdb_prompt $"\ 146 {pass "step after execlp call"} 147 -re "$gdb_prompt $" {fail "step after execlp call"} 148 timeout {fail "(timeout) step after execlp call"} 149 } 150 send_gdb "print global_i\n" 151 gdb_expect { 152 -re ".* = 0.*$gdb_prompt $"\ 153 {pass "print execd-program/global_i (after execlp)"} 154 -re "$gdb_prompt $" {fail "print execd-program/global_i (after execlp)"} 155 timeout {fail "(timeout) print execd-program/global_i (after execlp)"} 156 } 157 send_gdb "print local_j\n" 158 gdb_expect { 159 -re ".* = 2.*$gdb_prompt $"\ 160 {pass "print execd-program/local_j (after execlp)"} 161 -re "$gdb_prompt $" {fail "print execd-program/local_j (after execlp)"} 162 timeout {fail "(timeout) print execd-program/local_j (after execlp)"} 163 } 164 send_gdb "print local_k\n" 165 gdb_expect { 166 -re "No symbol \"local_k\" in current context.*$gdb_prompt $"\ 167 {pass "print follow-exec/local_k (after execlp)"} 168 -re "$gdb_prompt $" {fail "print follow-exec/local_k (after execlp)"} 169 timeout {fail "(timeout) print follow-exec/local_k (after execlp)"} 170 } 171 172 # Explicitly kill this program, or a subsequent rerun actually runs 173 # the exec'd program, not the original program... 174 zap_session 175 176 # Start the program running, and stop at main. 177 # 178 if ![runto_main] then { 179 perror "Couldn't run ${testfile} (2nd try)" 180 return 181 } 182 183 # Verify that we can catch an exec event, and then continue 184 # to follow through the exec. (Since there's a breakpoint on 185 # "main", it'll also be transferred to the exec'd program, 186 # and we expect to stop there.) 187 # 188 send_gdb "catch exec\n" 189 gdb_expect { 190 -re "Catchpoint .*(exec).*$gdb_prompt $"\ 191 {pass "set catch exec"} 192 -re "$gdb_prompt $" {fail "set catch exec"} 193 timeout {fail "(timeout) set catch exec"} 194 } 195 196 # Verify that the catchpoint is mentioned in an "info breakpoints", 197 # and further that the catchpoint mentions no program name. 198 # 199 send_gdb "info breakpoints\n" 200 gdb_expect { 201 -re ".*catch exec.*keep y.*$gdb_prompt $"\ 202 {pass "info shows catchpoint without exec pathname"} 203 -re ".*catch exec.*program \"\".*$gdb_prompt $"\ 204 {fail "info shows catchpoint without exec pathname"} 205 -re "$gdb_prompt $" {fail "info shows catchpoint without exec pathname"} 206 timeout {fail "(timeout) info shows catchpoint without exec pathname"} 207 } 208 209 # DTS CLLbs16760 210 # PA64 doesn't know about $START$ in dld.sl at this point. It should. 211 # - Michael Coulter 212 setup_xfail hppa2.0w-hp-hpux* CLLbs16760 213 send_gdb "continue\n" 214 gdb_expect { 215 -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .START..*$gdb_prompt $"\ 216 {pass "hit catch exec"} 217 -re "$gdb_prompt $" {fail "hit catch exec"} 218 timeout {fail "(timeout) hit catch exec"} 219 } 220 221 # DTS CLLbs16760 222 # test gets out of sync if previous test fails. 223 gdb_test "bt" ".*" "sync up after possible failure 1" 224 gdb_test "bt" "#0.*" "sync up after possible failure 2" 225 226 # Verify that the catchpoint is mentioned in an "info breakpoints", 227 # and further that the catchpoint managed to capture the exec'd 228 # program's name. 229 # 230 send_gdb "info breakpoints\n" 231 gdb_expect { 232 -re ".*catch exec .*program \".*${testfile2}\".*$gdb_prompt $"\ 233 {pass "info shows catchpoint exec pathname"} 234 -re "$gdb_prompt $" {fail "info shows catchpoint exec pathname"} 235 timeout {fail "(timeout) info shows catchpoint exec pathname"} 236 } 237 238 # Verify that we can continue from the catchpoint, and land in the 239 # main of the newly-exec'd program. 240 # 241 send_gdb "continue\n" 242 gdb_expect { 243 -re ".*${srcfile2}:23.*$gdb_prompt $"\ 244 {pass "continue after hit catch exec"} 245 -re "$gdb_prompt $" {fail "continue after hit catch exec"} 246 timeout {fail "(timeout) continue after hit catch exec"} 247 } 248 249 # Explicitly kill this program, or a subsequent rerun actually runs 250 # the exec'd program, not the original program... 251 zap_session 252 253 # Start the program running, and stop at main. 254 # 255 if ![runto_main] then { 256 perror "Couldn't run ${testfile} (3rd try)" 257 return 258 } 259 260 # Verify that we can follow through follow an execl() 261 # call. (We must jump around earlier exec* calls.) 262 # 263 send_gdb "tbreak 27\n" 264 gdb_expect { 265 -re "Breakpoint .*file .*${srcfile}, line 27.*$gdb_prompt $"\ 266 {pass "prepare to jump to execl call"} 267 -re "$gdb_prompt $" {fail "prepare to jump to execl call"} 268 timeout {fail "(timeout) prepare to jump to execl call"} 269 } 270 send_gdb "jump 27\n" 271 gdb_expect { 272 -re "main.* at .*${srcfile}:27.*$gdb_prompt $"\ 273 {pass "jump to execl call"} 274 -re "$gdb_prompt $" {fail "jump to execl call"} 275 timeout {fail "(timeout) jump to execl call"} 276 } 277 # Note that stepping through an exec call causes the step-count 278 # to be reset to zero. I.e.: you may specify "next 2" at the 279 # call, but you'll actually stop at the first breakpoint set in 280 # the newly-exec'd program, not after the remaining step-count 281 # reaches zero. 282 # 283 send_gdb "next 2\n" 284 gdb_expect { 285 -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\ 286 {pass "step through execl call"} 287 -re "$gdb_prompt $" {fail "step through execl call"} 288 timeout {fail "(timeout) step through execl call"} 289 } 290 send_gdb "next\n" 291 gdb_expect { 292 -re "26.*printf.*$gdb_prompt $"\ 293 {pass "step after execl call"} 294 -re "$gdb_prompt $" {fail "step after execl call"} 295 timeout {fail "(timeout) step after execl call"} 296 } 297 298 # Verify that we can print a local variable (which happens to be 299 # assigned the value of main's argc). 300 # 301 send_gdb "print local_j\n" 302 gdb_expect { 303 -re ".* = 3.*$gdb_prompt $"\ 304 {pass "print execd-program/local_j (after execl)"} 305 -re "$gdb_prompt $" {fail "print execd-program/local_j (after execl)"} 306 timeout {fail "(timeout) print execd-program/local_j (after execl)"} 307 } 308 309 # Explicitly kill this program, or a subsequent rerun actually runs 310 # the exec'd program, not the original program... 311 zap_session 312 313 # Start the program running, and stop at main. 314 # 315 if ![runto_main] then { 316 perror "Couldn't run ${testfile} (4th try)" 317 return 318 } 319 320 # Verify that we can follow through follow an execv() 321 # call. (We must jump around earlier exec* calls.) 322 # 323 send_gdb "tbreak 41\n" 324 gdb_expect { 325 -re "Breakpoint .*file .*${srcfile}, line 41.*$gdb_prompt $"\ 326 {pass "prepare to jump to execv call"} 327 -re "$gdb_prompt $" {fail "prepare to jump to execv call"} 328 timeout {fail "(timeout) prepare to jump to execv call"} 329 } 330 send_gdb "jump 41\n" 331 gdb_expect { 332 -re "main.* at .*${srcfile}:41.*$gdb_prompt $"\ 333 {pass "jump to execv call"} 334 -re "$gdb_prompt $" {fail "jump to execv call"} 335 timeout {fail "(timeout) jump to execv call"} 336 } 337 send_gdb "next\n" 338 gdb_expect { 339 -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\ 340 {pass "step through execv call"} 341 -re "$gdb_prompt $" {fail "step through execv call"} 342 timeout {fail "(timeout) step through execv call"} 343 } 344 send_gdb "next\n" 345 gdb_expect { 346 -re "26.*printf.*$gdb_prompt $"\ 347 {pass "step after execv call"} 348 -re "$gdb_prompt $" {fail "step after execv call"} 349 timeout {fail "(timeout) step after execv call"} 350 } 351 352 # Verify that we can print a local variable (which happens to be 353 # assigned the value of main's argc). 354 # 355 send_gdb "print local_j\n" 356 gdb_expect { 357 -re ".* = 2.*$gdb_prompt $"\ 358 {pass "print execd-program/local_j (after execv)"} 359 -re "$gdb_prompt $" {fail "print execd-program/local_j (after execv)"} 360 timeout {fail "(timeout) print execd-program/local_j (after execv)"} 361 } 362 363 # Explicitly kill this program, or a subsequent rerun actually runs 364 # the exec'd program, not the original program... 365 zap_session 366 367 # Start the program running, and stop at main. 368 # 369 if ![runto_main] then { 370 perror "Couldn't run ${testfile} (5th try)" 371 return 372 } 373 374 # Verify that we can just continue and thereby follow through an 375 # exec call. (Since the breakpoint on "main" is reset, we should 376 # just stop in main of the newly-exec'd program.) 377 # 378 send_gdb "continue\n" 379 gdb_expect { 380 -re "Executing new program: .*${testfile2}.*${srcfile2}:23.*int local_j = argc;.*$gdb_prompt $"\ 381 {pass "continue through exec"} 382 -re "$gdb_prompt $" {fail "continue through exec"} 383 timeout {fail "(timeout) continue through exec"} 384 } 385} 386 387# Start with a fresh gdb 388 389gdb_exit 390gdb_start 391gdb_reinitialize_dir $srcdir/$subdir 392gdb_load ${binfile} 393 394 395# This is a test of gdb's ability to follow a process through a 396# Unix exec() system call. 397# 398do_exec_tests 399 400return 0 401