1# Copyright 1997, 1999, 2007 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# Please email any bugs, comments, and/or additions to this file to: 17# bug-gdb@prep.ai.mit.edu 18 19if $tracelevel then { 20 strace $tracelevel 21 } 22 23if { ![isnative] } then { 24 continue 25} 26 27set prms_id 0 28set bug_id 0 29 30# NOTE drow/2002-12-06: I don't know what the referenced kernel problem 31# is, but it appears to be fixed in recent HP/UX versions. 32 33##if [istarget "hppa2.0w-hp-hpux*"] { 34## warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed." 35## return 0 36##} 37 38set testfile "foll-vfork" 39set testfile2 "vforked-prog" 40set srcfile ${testfile}.c 41set srcfile2 ${testfile2}.c 42set binfile ${objdir}/${subdir}/${testfile} 43set binfile2 ${objdir}/${subdir}/${testfile2} 44 45if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 46 untested foll-vfork.exp 47 return -1 48} 49 50if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } { 51 untested foll-vfork.exp 52 return -1 53} 54 55 56# Until "set follow-fork-mode" and "catch vfork" are implemented on 57# other targets... 58# 59if ![istarget "hppa*-hp-hpux*"] then { 60 continue 61} 62 63# Test to see if we are on an HP-UX 10.20 and if so, 64# do not run these tests as catching vfork is disabled for 65# 10.20. 66 67if [istarget "hppa*-hp-hpux10.20"] then { 68 return 0 69} 70 71# A few of these tests require a little more time than the standard 72# timeout allows. 73set oldtimeout $timeout 74set timeout [expr "$timeout + 10"] 75 76proc vfork_parent_follow_through_step {} { 77 global gdb_prompt 78 79 send_gdb "set follow parent\n" 80 gdb_expect { 81 -re "$gdb_prompt $" {pass "set follow parent, vfork through step"} 82 timeout {fail "set follow parent, vfork through step"} 83 } 84 send_gdb "next\n" 85 gdb_expect { 86 -re "Detaching after fork from.*13.*$gdb_prompt "\ 87 {pass "vfork parent follow, through step"} 88 -re "$gdb_prompt $" {fail "vfork parent follow, through step"} 89 timeout {fail "(timeout) vfork parent follow, through step" } 90 } 91 # The child has been detached; allow time for any output it might 92 # generate to arrive, so that output doesn't get confused with 93 # any gdb_expected debugger output from a subsequent testpoint. 94 # 95 exec sleep 1 96} 97 98proc vfork_parent_follow_to_bp {} { 99 global gdb_prompt 100 101 send_gdb "set follow parent\n" 102 gdb_expect { 103 -re "$gdb_prompt $" {pass "set follow parent, vfork to bp"} 104 timeout {fail "set follow parent, vfork to bp"} 105 } 106 send_gdb "break 18\n" 107 gdb_expect { 108 -re "$gdb_prompt $" {pass "break, vfork to bp"} 109 timeout {fail "break, vfork to bp"} 110 } 111 send_gdb "continue\n" 112 gdb_expect { 113 -re ".*Detaching after fork from process.*Breakpoint.*18.*$gdb_prompt "\ 114 {pass "vfork parent follow, to bp"} 115 -re "$gdb_prompt $" {fail "vfork parent follow, to bp"} 116 timeout {fail "(timeout) vfork parent follow, to bp" } 117 } 118 # The child has been detached; allow time for any output it might 119 # generate to arrive, so that output doesn't get confused with 120 # any expected debugger output from a subsequent testpoint. 121 # 122 exec sleep 1 123} 124 125proc vfork_and_exec_child_follow_to_main_bp {} { 126 global gdb_prompt 127 global binfile 128 129 send_gdb "set follow child\n" 130 gdb_expect { 131 -re "$gdb_prompt $" {pass "set follow child, vfork and exec to main bp"} 132 timeout {fail "set follow child, vfork and exec to main bp"} 133 } 134 send_gdb "continue\n" 135 gdb_expect { 136 -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\ 137 {pass "vfork and exec child follow, to main bp"} 138 -re "$gdb_prompt $" {fail "vfork and exec child follow, to main bp"} 139 timeout {fail "(timeout) vfork and exec child follow, to main bp" } 140 } 141 # The parent has been detached; allow time for any output it might 142 # generate to arrive, so that output doesn't get confused with 143 # any gdb_expected debugger output from a subsequent testpoint. 144 # 145 exec sleep 1 146 147 # Explicitly kill this child, or a subsequent rerun actually runs 148 # the exec'd child, not the original program... 149 send_gdb "kill\n" 150 gdb_expect { 151 -re ".*Kill the program being debugged.*y or n. $" { 152 send_gdb "y\n" 153 send_gdb "file $binfile\n" 154 gdb_expect { 155 -re ".*Load new symbol table from.*y or n. $" { 156 send_gdb "y\n" 157 gdb_expect { 158 -re "Reading symbols from.*$gdb_prompt $" {} 159 timeout { fail "loading symbols (timeout)"; return } 160 } 161 } 162 -re ".*gdb_prompt $" {} 163 timeout { fail "loading symbols (timeout)"; return } 164 } 165 } 166 -re ".*$gdb_prompt $" {} 167 timeout { fail "killing inferior (timeout)" ; return } 168 } 169} 170 171proc vfork_and_exec_child_follow_through_step {} { 172 global gdb_prompt 173 global binfile 174 175# This test cannot be performed prior to HP-UX 10.30, because ptrace-based 176# debugging of a vforking program basically doesn't allow the child to do 177# things like hit a breakpoint between a vfork and exec. This means that 178# saying "set follow child; next" at a vfork() call won't work, because 179# the implementation of "next" sets a "step resume" breakpoint at the 180# return from the vfork(), which the child will hit on its way to exec'ing. 181# 182 if { ![istarget "hppa*-*-hpux11.*"] } { 183 verbose "vfork child-following next test ignored for non-hppa or pre-HP/UX-10.30 targets." 184 return 0 185 } 186 187 send_gdb "set follow child\n" 188 gdb_expect { 189 -re "$gdb_prompt $" {pass "set follow child, vfork and exec through step"} 190 timeout {fail "set follow child, vfork and exec through step"} 191 } 192 send_gdb "next\n" 193 gdb_expect { 194 -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\ 195 {pass "vfork and exec child follow, through step"} 196 -re "$gdb_prompt $" {fail "vfork and exec child follow, through step"} 197 timeout {fail "(timeout) vfork and exec child follow, through step" } 198 } 199 # The parent has been detached; allow time for any output it might 200 # generate to arrive, so that output doesn't get confused with 201 # any expected debugger output from a subsequent testpoint. 202 # 203 exec sleep 1 204 205 # Explicitly kill this child, or a subsequent rerun actually runs 206 # the exec'd child, not the original program... 207 send_gdb "kill\n" 208 gdb_expect { 209 -re ".*Kill the program being debugged.*y or n. $" { 210 send_gdb "y\n" 211 send_gdb "file $binfile\n" 212 gdb_expect { 213 -re ".*Load new symbol table from.*y or n. $" { 214 send_gdb "y\n" 215 gdb_expect { 216 -re "Reading symbols from.*$gdb_prompt $" {} 217 timeout { fail "loading symbols (timeout)"; return } 218 } 219 } 220 -re ".*gdb_prompt $" {} 221 timeout { fail "loading symbols (timeout)"; return } 222 } 223 } 224 -re ".*$gdb_prompt $" {} 225 timeout { fail "killing inferior (timeout)" ; return } 226 } 227} 228 229proc tcatch_vfork_then_parent_follow {} { 230 global gdb_prompt 231 global srcfile 232 233 send_gdb "set follow parent\n" 234 gdb_expect { 235 -re "$gdb_prompt $" {pass "set follow parent, tcatch vfork"} 236 timeout {fail "set follow parent, tcatch vfork"} 237 } 238 send_gdb "tcatch vfork\n" 239 gdb_expect { 240 -re "Catchpoint .*(vfork).*$gdb_prompt $"\ 241 {pass "vfork parent follow, set tcatch vfork"} 242 -re "$gdb_prompt $" {fail "vfork parent follow, set tcatch vfork"} 243 timeout {fail "(timeout) vfork parent follow, set tcatch vfork"} 244 } 245 send_gdb "continue\n" 246# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs 247# stop you in "_vfork". 248 gdb_expect { 249 -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\ 250 {pass "vfork parent follow, tcatch vfork"} 251 -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\ 252 {pass "vfork parent follow, tcatch vfork"} 253 -re "$gdb_prompt $" {fail "vfork parent follow, tcatch vfork"} 254 timeout {fail "(timeout) vfork parent follow, tcatch vfork"} 255 } 256 send_gdb "finish\n" 257 gdb_expect { 258 -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:12.*$gdb_prompt "\ 259 {pass "vfork parent follow, finish after tcatch vfork"} 260 -re "$gdb_prompt $" {fail "vfork parent follow, finish after tcatch vfork"} 261 timeout {fail "(timeout) vfork parent follow, finish after tcatch vfork" } 262 } 263 # The child has been detached; allow time for any output it might 264 # generate to arrive, so that output doesn't get confused with 265 # any expected debugger output from a subsequent testpoint. 266 # 267 exec sleep 1 268} 269 270proc tcatch_vfork_then_child_follow {} { 271 global gdb_prompt 272 global srcfile2 273 274 send_gdb "set follow child\n" 275 gdb_expect { 276 -re "$gdb_prompt $" {pass "set follow child, tcatch vfork"} 277 timeout {fail "set follow child, tcatch vfork"} 278 } 279 send_gdb "tcatch vfork\n" 280 gdb_expect { 281 -re "Catchpoint .*(vfork).*$gdb_prompt $"\ 282 {pass "vfork child follow, set tcatch vfork"} 283 -re "$gdb_prompt $" {fail "vfork child follow, set tcatch vfork"} 284 timeout {fail "(timeout) vfork child follow, set tcatch vfork"} 285 } 286 send_gdb "continue\n" 287# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs 288# stop you in "_vfork". 289 gdb_expect { 290 -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\ 291 {pass "vfork child follow, tcatch vfork"} 292 -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\ 293 {pass "vfork child follow, tcatch vfork"} 294 -re "$gdb_prompt $" {fail "vfork child follow, tcatch vfork"} 295 timeout {fail "(timeout) vfork child follow, tcatch vfork"} 296 } 297 send_gdb "finish\n" 298 gdb_expect { 299 -re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt "\ 300 {pass "vfork child follow, finish after tcatch vfork"} 301 -re "$gdb_prompt $" {fail "vfork child follow, finish after tcatch vfork"} 302 timeout {fail "(timeout) vfork child follow, finish after tcatch vfork" } 303 } 304 # The parent has been detached; allow time for any output it might 305 # generate to arrive, so that output doesn't get confused with 306 # any expected debugger output from a subsequent testpoint. 307 # 308 exec sleep 1 309} 310 311proc do_vfork_and_exec_tests {} { 312 global gdb_prompt 313 314 # Try following the parent process by stepping through a call to 315 # vfork. Do this without catchpoints. 316 if [runto_main] then { vfork_parent_follow_through_step } 317 318 # Try following the parent process by setting a breakpoint on the 319 # other side of a vfork, and running to that point. Do this 320 # without catchpoints. 321 if [runto_main] then { vfork_parent_follow_to_bp } 322 323 # Try following the child process by just continuing through the 324 # vfork, and letting the parent's breakpoint on "main" be auto- 325 # magically reset in the child. 326 # 327 if [runto_main] then { vfork_and_exec_child_follow_to_main_bp } 328 329 # Try following the child process by stepping through a call to 330 # vfork. The child also executes an exec. Since the child cannot 331 # be debugged until after it has exec'd, and since there's a bp on 332 # "main" in the parent, and since the bp's for the parent are 333 # recomputed in the exec'd child, the step through a vfork should 334 # land us in the "main" for the exec'd child, too. 335 # 336 if [runto_main] then { vfork_and_exec_child_follow_through_step } 337 338 # Try catching a vfork, and stepping out to the parent. 339 # 340 if [runto_main] then { tcatch_vfork_then_parent_follow } 341 342 # Try catching a vfork, and stepping out to the child. 343 # 344 if [runto_main] then { tcatch_vfork_then_child_follow } 345 346 # Test the ability to follow both child and parent of a vfork. Do 347 # this without catchpoints. 348 # ??rehrauer: NYI. Will add testpoints here when implemented. 349 # 350 351 # Test the ability to have the debugger ask the user at vfork-time 352 # whether to follow the parent, child or both. Do this without 353 # catchpoints. 354 # ??rehrauer: NYI. Will add testpoints here when implemented. 355 # 356} 357 358# Start with a fresh gdb 359 360gdb_exit 361gdb_start 362gdb_reinitialize_dir $srcdir/$subdir 363gdb_load ${binfile} 364 365 366# This is a test of gdb's ability to follow the parent or child 367# of a Unix vfork() system call. (The child will subsequently 368# call a variant of a Unix exec() system call.) 369# 370do_vfork_and_exec_tests 371 372set timeout $oldtimeout 373return 0 374