| OLD | NEW |
| 1 # Copyright 1997, 1999, 2007-2012 Free Software Foundation, Inc. | 1 # Copyright 1997-2013 Free Software Foundation, Inc. |
| 2 | 2 |
| 3 # This program is free software; you can redistribute it and/or modify | 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 | 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 | 5 # the Free Software Foundation; either version 3 of the License, or |
| 6 # (at your option) any later version. | 6 # (at your option) any later version. |
| 7 # | 7 # |
| 8 # This program is distributed in the hope that it will be useful, | 8 # This program is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 # GNU General Public License for more details. | 11 # GNU General Public License for more details. |
| 12 # | 12 # |
| 13 # You should have received a copy of the GNU General Public License | 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/>. | 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | 15 |
| 16 # Various tests of gdb's ability to follow the parent or child of a |
| 17 # Unix vfork system call. A vfork parent is blocked until the child |
| 18 # either execs or exits --- since those events take somewhat different |
| 19 # code paths in GDB, both variants are exercised. |
| 20 |
| 16 if { [is_remote target] || ![isnative] } then { | 21 if { [is_remote target] || ![isnative] } then { |
| 17 continue | 22 continue |
| 18 } | 23 } |
| 19 | 24 |
| 20 # Until "set follow-fork-mode" and "catch vfork" are implemented on | 25 # Until "set follow-fork-mode" and "catch vfork" are implemented on |
| 21 # other targets... | 26 # other targets... |
| 22 # | 27 # |
| 23 if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { | 28 if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { |
| 24 continue | 29 continue |
| 25 } | 30 } |
| 26 | 31 |
| 27 # Test to see if we are on an HP-UX 10.20 and if so, | 32 # Test to see if we are on an HP-UX 10.20 and if so, |
| 28 # do not run these tests as catching vfork is disabled for | 33 # do not run these tests as catching vfork is disabled for |
| 29 # 10.20. | 34 # 10.20. |
| 30 | 35 |
| 31 if [istarget "hppa*-hp-hpux10.20"] then { | 36 if [istarget "hppa*-hp-hpux10.20"] then { |
| 32 return 0 | 37 return 0 |
| 33 } | 38 } |
| 34 | 39 |
| 35 # NOTE drow/2002-12-06: I don't know what the referenced kernel problem | 40 # NOTE drow/2002-12-06: I don't know what the referenced kernel problem |
| 36 # is, but it appears to be fixed in recent HP/UX versions. | 41 # is, but it appears to be fixed in recent HP/UX versions. |
| 37 | 42 |
| 38 ##if [istarget "hppa2.0w-hp-hpux*"] { | 43 ##if [istarget "hppa2.0w-hp-hpux*"] { |
| 39 ## warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem i
s fixed." | 44 ## warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem i
s fixed." |
| 40 ## return 0 | 45 ## return 0 |
| 41 ##} | 46 ##} |
| 42 | 47 |
| 43 global srcfile | 48 standard_testfile |
| 44 set testfile "foll-vfork" | |
| 45 set testfile2 "vforked-prog" | |
| 46 set srcfile ${testfile}.c | |
| 47 set srcfile2 ${testfile2}.c | |
| 48 set binfile ${objdir}/${subdir}/${testfile} | |
| 49 set binfile2 ${objdir}/${subdir}/${testfile2} | |
| 50 | 49 |
| 51 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
ug}] != "" } { | 50 set compile_options debug |
| 52 untested foll-vfork.exp | 51 set dirname [relative_filename [pwd] [file dirname $binfile]] |
| 53 return -1 | 52 lappend compile_options "additional_flags=-DBASEDIR=\"$dirname\"" |
| 53 |
| 54 if {[build_executable $testfile.exp $testfile $srcfile $compile_options] == -1}
{ |
| 55 untested "failed to compile $testfile" |
| 56 return -1 |
| 54 } | 57 } |
| 55 | 58 |
| 56 if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {d
ebug}] != "" } { | 59 set testfile2 "vforked-prog" |
| 57 untested foll-vfork.exp | 60 set srcfile2 ${testfile2}.c |
| 58 return -1 | 61 |
| 62 if {[build_executable $testfile.exp $testfile2 $srcfile2 $compile_options] == -1
} { |
| 63 untested "failed to compile $testfile2" |
| 64 return -1 |
| 59 } | 65 } |
| 60 | 66 |
| 61 # A few of these tests require a little more time than the standard | 67 # A few of these tests require a little more time than the standard |
| 62 # timeout allows. | 68 # timeout allows. |
| 63 set oldtimeout $timeout | 69 set oldtimeout $timeout |
| 64 set timeout [expr "$timeout + 10"] | 70 set timeout [expr "$timeout + 10"] |
| 65 | 71 |
| 72 # Start with a fresh GDB, with verbosity enabled, and run to main. On |
| 73 # error, behave as "return", so we don't try to continue testing with |
| 74 # a borked session. |
| 75 proc setup_gdb {} { |
| 76 global testfile |
| 77 |
| 78 clean_restart $testfile |
| 79 |
| 80 # The "Detaching..." and "Attaching..." messages may be hidden by |
| 81 # default. |
| 82 gdb_test_no_output "set verbose" |
| 83 |
| 84 if ![runto_main] { |
| 85 return -code return |
| 86 } |
| 87 } |
| 88 |
| 66 proc check_vfork_catchpoints {} { | 89 proc check_vfork_catchpoints {} { |
| 67 global gdb_prompt | 90 global gdb_prompt |
| 68 global has_vfork_catchpoints | 91 global has_vfork_catchpoints |
| 69 | 92 |
| 93 setup_gdb |
| 94 |
| 70 # Verify that the system supports "catch vfork". | 95 # Verify that the system supports "catch vfork". |
| 71 gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork c
atchpoint" | 96 gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork c
atchpoint" |
| 72 set has_vfork_catchpoints 0 | 97 set has_vfork_catchpoints 0 |
| 73 gdb_test_multiple "continue" "continue to first vfork catchpoint" { | 98 gdb_test_multiple "continue" "continue to first vfork catchpoint" { |
| 74 -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt
$" { | 99 -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt
$" { |
| 75 unsupported "continue to first vfork catchpoint" | 100 unsupported "continue to first vfork catchpoint" |
| 76 } | 101 } |
| 77 -re ".*Catchpoint.*$gdb_prompt $" { | 102 -re ".*Catchpoint.*$gdb_prompt $" { |
| 78 set has_vfork_catchpoints 1 | 103 set has_vfork_catchpoints 1 |
| 79 pass "continue to first vfork catchpoint" | 104 pass "continue to first vfork catchpoint" |
| 80 } | 105 } |
| 81 } | 106 } |
| 82 | 107 |
| 83 if {$has_vfork_catchpoints == 0} { | 108 if {$has_vfork_catchpoints == 0} { |
| 84 unsupported "vfork catchpoints" | 109 unsupported "vfork catchpoints" |
| 85 return -code return | 110 return -code return |
| 86 } | 111 } |
| 87 } | 112 } |
| 88 | 113 |
| 89 proc vfork_parent_follow_through_step {} { | 114 proc vfork_parent_follow_through_step {} { |
| 90 global gdb_prompt | 115 with_test_prefix "vfork parent follow, through step" { |
| 91 | 116 global gdb_prompt |
| 92 send_gdb "set follow-fork parent\n" | 117 |
| 93 gdb_expect { | 118 setup_gdb |
| 94 -re "$gdb_prompt $" {pass "set follow-fork parent, vfork through step"} | 119 |
| 95 timeout {fail "set follow-fork parent, vfork through step"} | 120 gdb_test_no_output "set follow-fork parent" |
| 96 } | 121 |
| 97 send_gdb "next\n" | 122 set test "step" |
| 98 gdb_expect { | 123 gdb_test_multiple "next" $test { |
| 99 -re "Detaching after fork from.*13.*$gdb_prompt "\ | 124 -re "Detaching after fork from.*if \\(pid == 0\\).*$gdb_prompt " { |
| 100 {pass "vfork parent follow, through step"} | 125 » pass $test |
| 101 -re "$gdb_prompt $" {fail "vfork parent follow, through step"} | 126 } |
| 102 timeout {fail "(timeout) vfork parent follow, through step" } | |
| 103 } | 127 } |
| 104 # The child has been detached; allow time for any output it might | 128 # The child has been detached; allow time for any output it might |
| 105 # generate to arrive, so that output doesn't get confused with | 129 # generate to arrive, so that output doesn't get confused with |
| 106 # any gdb_expected debugger output from a subsequent testpoint. | 130 # any gdb_expected debugger output from a subsequent testpoint. |
| 107 # | 131 # |
| 108 exec sleep 1 | 132 exec sleep 1 |
| 109 } | 133 }} |
| 110 | 134 |
| 111 proc vfork_parent_follow_to_bp {} { | 135 proc vfork_parent_follow_to_bp {} { |
| 136 with_test_prefix "vfork parent follow, to bp" { |
| 112 global gdb_prompt | 137 global gdb_prompt |
| 113 global srcfile | 138 global srcfile |
| 114 | 139 |
| 115 send_gdb "set follow-fork parent\n" | 140 setup_gdb |
| 116 gdb_expect { | 141 |
| 117 -re "$gdb_prompt $" {pass "set follow-fork parent, vfork to bp"} | 142 gdb_test_no_output "set follow-fork parent" |
| 118 timeout {fail "set follow-fork parent, vfork to bp"} | 143 |
| 119 } | 144 set bp_location [gdb_get_line_number "printf (\"I'm the proud parent of child
"] |
| 120 send_gdb "break ${srcfile}:18\n" | 145 gdb_test "break ${srcfile}:${bp_location}" ".*" "break, vfork to bp" |
| 121 gdb_expect { | 146 |
| 122 -re "$gdb_prompt $" {pass "break, vfork to bp"} | 147 set test "continue to bp" |
| 123 timeout {fail "break, vfork to bp"} | 148 gdb_test_multiple "continue" $test { |
| 124 } | 149 -re ".*Detaching after fork from child process.*Breakpoint.*${bp_location
}.*$gdb_prompt " { |
| 125 send_gdb "continue\n" | 150 » pass $test |
| 126 gdb_expect { | 151 } |
| 127 -re ".*Detaching after fork from child process.*Breakpoint.*18.*$gdb_promp
t "\ | |
| 128 {pass "vfork parent follow, to bp"} | |
| 129 -re "$gdb_prompt $" {fail "vfork parent follow, to bp"} | |
| 130 timeout {fail "(timeout) vfork parent follow, to bp" } | |
| 131 } | 152 } |
| 132 # The child has been detached; allow time for any output it might | 153 # The child has been detached; allow time for any output it might |
| 133 # generate to arrive, so that output doesn't get confused with | 154 # generate to arrive, so that output doesn't get confused with |
| 134 # any expected debugger output from a subsequent testpoint. | 155 # any expected debugger output from a subsequent testpoint. |
| 135 # | 156 # |
| 136 exec sleep 1 | 157 exec sleep 1 |
| 137 } | 158 }} |
| 159 |
| 160 proc vfork_child_follow_to_exit {} { |
| 161 with_test_prefix "vfork child follow, to exit" { |
| 162 global gdb_prompt |
| 163 |
| 164 setup_gdb |
| 165 |
| 166 gdb_test_no_output "set follow-fork child" |
| 167 |
| 168 set test "continue to child exit" |
| 169 gdb_test_multiple "continue" $test { |
| 170 -re "Couldn't get registers.*$gdb_prompt " { |
| 171 » # PR gdb/14766 |
| 172 » fail "$test" |
| 173 } |
| 174 -re "Attaching after.* vfork to.*Detaching vfork parent .* after child exi
t.*$gdb_prompt " { |
| 175 » pass $test |
| 176 } |
| 177 } |
| 178 # The parent has been detached; allow time for any output it might |
| 179 # generate to arrive, so that output doesn't get confused with |
| 180 # any gdb_expected debugger output from a subsequent testpoint. |
| 181 # |
| 182 exec sleep 1 |
| 183 }} |
| 138 | 184 |
| 139 proc vfork_and_exec_child_follow_to_main_bp {} { | 185 proc vfork_and_exec_child_follow_to_main_bp {} { |
| 140 global gdb_prompt | 186 with_test_prefix "vfork and exec child follow, to main bp" { |
| 141 global binfile | 187 global gdb_prompt |
| 142 | 188 global srcfile2 |
| 143 send_gdb "set follow-fork child\n" | 189 |
| 144 gdb_expect { | 190 setup_gdb |
| 145 -re "$gdb_prompt $" {pass "set follow-fork child, vfork and exec to main b
p"} | 191 |
| 146 timeout {fail "set follow-fork child, vfork and exec to main bp"} | 192 gdb_test_no_output "set follow-fork child" |
| 147 } | 193 |
| 148 send_gdb "continue\n" | 194 set linenum [gdb_get_line_number "printf(\"Hello from vforked-prog" ${srcfile
2}] |
| 149 gdb_expect { | 195 |
| 150 -re "Attaching after.* vfork to.*xecuting new program.*Breakpoint.*vforked
-prog.c:9.*$gdb_prompt "\ | 196 set test "continue to bp" |
| 151 {pass "vfork and exec child follow, to main bp"} | 197 gdb_test_multiple "continue" $test { |
| 152 -re "$gdb_prompt $" {fail "vfork and exec child follow, to main bp"} | 198 -re "Attaching after.* vfork to.*xecuting new program.*Breakpoint.*vforked
-prog.c:${linenum}.*$gdb_prompt " { |
| 153 timeout {fail "(timeout) vfork and exec child follow, to main bp"
} | 199 » pass $test |
| 200 } |
| 154 } | 201 } |
| 155 # The parent has been detached; allow time for any output it might | 202 # The parent has been detached; allow time for any output it might |
| 156 # generate to arrive, so that output doesn't get confused with | 203 # generate to arrive, so that output doesn't get confused with |
| 157 # any gdb_expected debugger output from a subsequent testpoint. | 204 # any gdb_expected debugger output from a subsequent testpoint. |
| 158 # | 205 # |
| 159 exec sleep 1 | 206 exec sleep 1 |
| 160 | 207 }} |
| 161 # Explicitly kill this child, or a subsequent rerun actually runs | |
| 162 # the exec'd child, not the original program... | |
| 163 send_gdb "kill\n" | |
| 164 gdb_expect { | |
| 165 -re ".*Kill the program being debugged.*y or n. $" { | |
| 166 gdb_test_no_output "y" "" | |
| 167 send_gdb "file $binfile\n" | |
| 168 gdb_expect { | |
| 169 -re ".*Load new symbol table from.*y or n. $" { | |
| 170 send_gdb "y\n" | |
| 171 gdb_expect { | |
| 172 -re "Reading symbols from.*$gdb_prompt $" {} | |
| 173 timeout { fail "loading symbols (timeout)"; return } | |
| 174 } | |
| 175 } | |
| 176 -re ".*gdb_prompt $" {} | |
| 177 timeout { fail "loading symbols (timeout)"; return } | |
| 178 } | |
| 179 } | |
| 180 -re ".*$gdb_prompt $" {} | |
| 181 timeout { fail "killing inferior (timeout)" ; return } | |
| 182 } | |
| 183 } | |
| 184 | 208 |
| 185 proc vfork_and_exec_child_follow_through_step {} { | 209 proc vfork_and_exec_child_follow_through_step {} { |
| 186 global gdb_prompt | 210 with_test_prefix "vfork and exec child follow, through step" { |
| 187 global binfile | 211 global gdb_prompt |
| 188 | 212 global srcfile2 |
| 189 # This test cannot be performed prior to HP-UX 10.30, because ptrace-based | 213 |
| 190 # debugging of a vforking program basically doesn't allow the child to do | 214 if { [istarget "hppa*-*-hpux*"] && ![istarget "hppa*-*-hpux11.*"] } { |
| 191 # things like hit a breakpoint between a vfork and exec. This means that | 215 # This test cannot be performed prior to HP-UX 10.30, because |
| 192 # saying "set follow-fork child; next" at a vfork() call won't work, because | 216 # ptrace-based debugging of a vforking program basically doesn't |
| 193 # the implementation of "next" sets a "step resume" breakpoint at the | 217 # allow the child to do things like hit a breakpoint between a |
| 194 # return from the vfork(), which the child will hit on its way to exec'ing. | 218 # vfork and exec. This means that saying "set follow-fork |
| 195 # | 219 # child; next" at a vfork() call won't work, because the |
| 196 if { ![istarget "hppa*-*-hpux11.*"] } { | 220 # implementation of "next" sets a "step resume" breakpoint at |
| 197 verbose "vfork child-following next test ignored for non-hppa or pre-HP/UX
-10.30 targets." | 221 # the return from the vfork(), which the child will hit on its |
| 222 # way to exec'ing. |
| 223 # |
| 224 verbose "vfork child-following next test ignored for pre-HP/UX-10.30 targe
ts." |
| 198 return 0 | 225 return 0 |
| 199 } | 226 } |
| 200 | 227 |
| 201 send_gdb "set follow-fork child\n" | 228 setup_gdb |
| 202 gdb_expect { | 229 |
| 203 -re "$gdb_prompt $" {pass "set follow-fork child, vfork and exec through s
tep"} | 230 gdb_test_no_output "set follow-fork child" |
| 204 timeout {fail "set follow-fork child, vfork and exec through step"
} | 231 |
| 205 } | 232 set test "step over vfork" |
| 206 send_gdb "next\n" | 233 if { [istarget "hppa*-*-hpux*"]} { |
| 207 gdb_expect { | 234 # Since the child cannot be debugged until after it has exec'd, |
| 208 -re "Attaching after fork to.*Executing new program.*Breakpoint.*vforked-p
rog.c:9.*$gdb_prompt "\ | 235 # and since there's a bp on "main" in the parent, and since the |
| 209 {pass "vfork and exec child follow, through step"} | 236 # bp's for the parent are recomputed in the exec'd child, the |
| 210 -re "$gdb_prompt $" {fail "vfork and exec child follow, through step"} | 237 # step through a vfork should land us in the "main" for the |
| 211 timeout {fail "(timeout) vfork and exec child follow, through step
" } | 238 # exec'd child, too. |
| 212 } | 239 # |
| 213 # The parent has been detached; allow time for any output it might | 240 set linenum [gdb_get_line_number "printf(\"Hello from vforked-prog" ${src
file2}] |
| 214 # generate to arrive, so that output doesn't get confused with | 241 gdb_test_multiple "next" $test { |
| 215 # any expected debugger output from a subsequent testpoint. | 242 » -re "Attaching after fork to.*Executing new program.*Breakpoint.*vfor
ked-prog.c:${linenum}.*$gdb_prompt " { |
| 216 # | 243 » pass "$test" |
| 217 exec sleep 1 | 244 » } |
| 218 | 245 } |
| 219 # Explicitly kill this child, or a subsequent rerun actually runs | 246 } else { |
| 220 # the exec'd child, not the original program... | 247 # The ideal support is to be able to debug the child even |
| 221 send_gdb "kill\n" | 248 # before it execs. Thus, "next" lands on the next line after |
| 222 gdb_expect { | 249 # the vfork. |
| 223 -re ".*Kill the program being debugged.*y or n. $" { | 250 gdb_test_multiple "next" $test { |
| 224 gdb_test_no_output "y" "" | 251 » -re "Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_promp
t " { |
| 225 send_gdb "file $binfile\n" | 252 » pass "$test" |
| 226 gdb_expect { | 253 » } |
| 227 -re ".*Load new symbol table from.*y or n. $" { | 254 } |
| 228 send_gdb "y\n" | 255 } |
| 229 gdb_expect { | 256 # The parent has been detached; allow time for any output it might |
| 230 -re "Reading symbols from.*$gdb_prompt $" {} | 257 # generate to arrive, so that output doesn't get confused with |
| 231 timeout { fail "loading symbols (timeout)"; return } | 258 # any expected debugger output from a subsequent testpoint. |
| 232 } | 259 # |
| 233 } | 260 exec sleep 1 |
| 234 -re ".*gdb_prompt $" {} | 261 }} |
| 235 timeout { fail "loading symbols (timeout)"; return } | |
| 236 } | |
| 237 } | |
| 238 -re ".*$gdb_prompt $" {} | |
| 239 timeout { fail "killing inferior (timeout)" ; return } | |
| 240 } | |
| 241 } | |
| 242 | 262 |
| 243 proc tcatch_vfork_then_parent_follow {} { | 263 proc tcatch_vfork_then_parent_follow {} { |
| 264 with_test_prefix "vfork parent follow, finish after tcatch vfork" { |
| 244 global gdb_prompt | 265 global gdb_prompt |
| 245 global srcfile | 266 global srcfile |
| 246 | 267 |
| 247 send_gdb "set follow-fork parent\n" | 268 setup_gdb |
| 248 gdb_expect { | 269 |
| 249 -re "$gdb_prompt $" {pass "set follow-fork parent, tcatch vfork"} | 270 gdb_test_no_output "set follow-fork parent" |
| 250 timeout {fail "set follow-fork parent, tcatch vfork"} | 271 |
| 251 } | 272 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" |
| 252 send_gdb "tcatch vfork\n" | 273 |
| 253 gdb_expect { | 274 # HP-UX 10.20 seems to stop you in "vfork", while more recent |
| 254 -re "Catchpoint .*(vfork).*$gdb_prompt $"\ | 275 # HP-UXs stop you in "_vfork". |
| 255 {pass "vfork parent follow, set tcatch vfork"} | 276 set test "continue to vfork" |
| 256 -re "$gdb_prompt $" {fail "vfork parent follow, set tcatch vfork"} | 277 gdb_test_multiple "continue" $test { |
| 257 timeout {fail "(timeout) vfork parent follow, set tcatch vfork"} | 278 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " { |
| 258 } | 279 » pass $test |
| 259 send_gdb "continue\n" | 280 } |
| 260 # HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs | 281 -re "vfork \\(\\) at.*$gdb_prompt " { |
| 261 # stop you in "_vfork". | 282 » pass $test |
| 262 gdb_expect { | 283 } |
| 263 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt "\ | 284 } |
| 264 {pass "vfork parent follow, tcatch vfork"} | 285 |
| 265 -re "vfork \\(\\) at.*$gdb_prompt "\ | 286 set linenum [gdb_get_line_number "pid = vfork ();"] |
| 266 {pass "vfork parent follow, tcatch vfork"} | 287 set test "finish" |
| 267 -re "$gdb_prompt $" {fail "vfork parent follow, tcatch vfork"} | 288 gdb_test_multiple "finish" $test { |
| 268 timeout {fail "(timeout) vfork parent follow, tcatch vfork"} | 289 -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile
}:${linenum}.*$gdb_prompt " { |
| 269 } | 290 » pass $test |
| 270 send_gdb "finish\n" | 291 } |
| 271 gdb_expect { | |
| 272 -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile
}:12.*$gdb_prompt "\ | |
| 273 {pass "vfork parent follow, finish after tcatch vfork"} | |
| 274 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$
gdb_prompt " { | 292 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$
gdb_prompt " { |
| 275 send_gdb "finish\n" | 293 send_gdb "finish\n" |
| 276 exp_continue | 294 exp_continue |
| 277 } | 295 } |
| 278 -re "$gdb_prompt $" {fail "vfork parent follow, finish after tcatch vfork"
} | |
| 279 timeout {fail "(timeout) vfork parent follow, finish after tcatch
vfork" } | |
| 280 } | 296 } |
| 281 # The child has been detached; allow time for any output it might | 297 # The child has been detached; allow time for any output it might |
| 282 # generate to arrive, so that output doesn't get confused with | 298 # generate to arrive, so that output doesn't get confused with |
| 283 # any expected debugger output from a subsequent testpoint. | 299 # any expected debugger output from a subsequent testpoint. |
| 284 # | 300 # |
| 285 exec sleep 1 | 301 exec sleep 1 |
| 286 } | 302 }} |
| 287 | 303 |
| 288 proc tcatch_vfork_then_child_follow {} { | 304 proc tcatch_vfork_then_child_follow_exec {} { |
| 305 with_test_prefix "vfork child follow, finish after tcatch vfork" { |
| 289 global gdb_prompt | 306 global gdb_prompt |
| 290 global srcfile | 307 global srcfile |
| 291 global srcfile2 | 308 global srcfile2 |
| 292 | 309 |
| 293 send_gdb "set follow-fork child\n" | 310 setup_gdb |
| 294 gdb_expect { | 311 |
| 295 -re "$gdb_prompt $" {pass "set follow-fork child, tcatch vfork"} | 312 gdb_test_no_output "set follow-fork child" |
| 296 timeout {fail "set follow-fork child, tcatch vfork"} | 313 |
| 297 } | 314 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" |
| 298 send_gdb "tcatch vfork\n" | 315 |
| 299 gdb_expect { | 316 # HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs |
| 300 -re "Catchpoint .*(vfork).*$gdb_prompt $"\ | 317 # stop you in "_vfork". |
| 301 {pass "vfork child follow, set tcatch vfork"} | 318 set test "continue to vfork" |
| 302 -re "$gdb_prompt $" {fail "vfork child follow, set tcatch vfork"} | 319 gdb_test_multiple "continue" $test { |
| 303 timeout {fail "(timeout) vfork child follow, set tcatch vfork"} | 320 -re "vfork \\(\\) at .*$gdb_prompt $" { |
| 304 } | 321 » pass $test |
| 305 send_gdb "continue\n" | 322 } |
| 306 # HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs | 323 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " { |
| 307 # stop you in "_vfork". | 324 » pass $test |
| 308 gdb_expect { | 325 } |
| 309 -re "vfork \\(\\) at .*$gdb_prompt $"\ | 326 } |
| 310 {pass "vfork child follow, tcatch vfork"} | 327 |
| 311 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt "\ | 328 set linenum1 [gdb_get_line_number "pid = vfork ();"] |
| 312 {pass "vfork child follow, tcatch vfork"} | 329 set linenum2 [gdb_get_line_number "printf(\"Hello from vforked-prog" ${srcfil
e2}] |
| 313 -re "$gdb_prompt $" {fail "vfork child follow, tcatch vfork"} | 330 |
| 314 timeout {fail "(timeout) vfork child follow, tcatch vfork"} | 331 set test "finish" |
| 315 } | 332 gdb_test_multiple "finish" $test { |
| 316 send_gdb "finish\n" | 333 -re "Run till exit from.*vfork.*${srcfile}:${linenum1}.*$gdb_prompt " { |
| 317 gdb_expect { | 334 » pass $test |
| 318 -re "Run till exit from.*vfork.*${srcfile}:12.*$gdb_prompt "\ | 335 } |
| 319 {pass "vfork child follow, finish after tcatch vfork"} | |
| 320 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$
gdb_prompt " { | 336 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$
gdb_prompt " { |
| 321 send_gdb "finish\n" | 337 send_gdb "finish\n" |
| 322 exp_continue | 338 exp_continue |
| 323 } | 339 } |
| 324 -re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt "\ | 340 -re "Run till exit from.*vfork.*${srcfile2}:${linenum2}.*$gdb_prompt " { |
| 325 {pass "vfork child follow, finish after tcatch vfork (foll
owed exec)"} | 341 » pass "$test (followed exec)" |
| 326 -re "$gdb_prompt $" {fail "vfork child follow, finish after tcatch vfork"} | 342 } |
| 327 timeout {fail "(timeout) vfork child follow, finish after tcatch v
fork" } | 343 } |
| 328 } | 344 # The parent has been detached; allow time for any output it might |
| 329 # The parent has been detached; allow time for any output it might | 345 # generate to arrive, so that output doesn't get confused with |
| 330 # generate to arrive, so that output doesn't get confused with | 346 # any expected debugger output from a subsequent testpoint. |
| 331 # any expected debugger output from a subsequent testpoint. | 347 # |
| 332 # | 348 exec sleep 1 |
| 333 exec sleep 1 | 349 }} |
| 334 } | 350 |
| 335 | 351 proc tcatch_vfork_then_child_follow_exit {} { |
| 336 proc do_vfork_and_exec_tests {} { | 352 with_test_prefix "vfork child follow, finish after tcatch vfork" { |
| 337 global gdb_prompt | 353 global gdb_prompt |
| 338 | 354 global srcfile |
| 339 # Check that vfork catchpoints are supported, as an indicator for whether | 355 |
| 340 # vfork-following is supported. | 356 setup_gdb |
| 341 if [runto_main] then { check_vfork_catchpoints } | 357 |
| 358 gdb_test_no_output "set follow-fork child" |
| 359 |
| 360 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" |
| 361 |
| 362 # HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs |
| 363 # stop you in "_vfork". |
| 364 set test "continue to vfork" |
| 365 gdb_test_multiple "continue" $test { |
| 366 -re "vfork \\(\\) at .*$gdb_prompt $" { |
| 367 » pass $test |
| 368 } |
| 369 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " { |
| 370 » pass $test |
| 371 } |
| 372 } |
| 373 |
| 374 set test "finish" |
| 375 gdb_test_multiple "finish" $test { |
| 376 -re "Run till exit from.*vfork.*exited normally.*$gdb_prompt " { |
| 377 » setup_kfail "gdb/14762" *-*-* |
| 378 » fail $test |
| 379 } |
| 380 -re "Run till exit from.*vfork.*pid = vfork \\(\\).*$gdb_prompt " { |
| 381 » pass $test |
| 382 } |
| 383 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$
gdb_prompt " { |
| 384 » send_gdb "finish\n" |
| 385 » exp_continue |
| 386 } |
| 387 } |
| 388 # The parent has been detached; allow time for any output it might |
| 389 # generate to arrive, so that output doesn't get confused with |
| 390 # any expected debugger output from a subsequent testpoint. |
| 391 # |
| 392 exec sleep 1 |
| 393 }} |
| 394 |
| 395 proc vfork_relations_in_info_inferiors { variant } { |
| 396 with_test_prefix "vfork relations in info inferiors" { |
| 397 global gdb_prompt |
| 398 |
| 399 setup_gdb |
| 400 |
| 401 gdb_test_no_output "set follow-fork child" |
| 402 |
| 403 set test "step over vfork" |
| 404 gdb_test_multiple "next" $test { |
| 405 -re "Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt "
{ |
| 406 » pass "$test" |
| 407 } |
| 408 } |
| 409 |
| 410 gdb_test "info inferiors" \ |
| 411 ".*is vfork child of inferior 1.*is vfork parent of inferior 2" \ |
| 412 "info inferiors shows vfork parent/child relation" |
| 413 |
| 414 if { $variant == "exec" } { |
| 415 global srcfile2 |
| 416 |
| 417 set linenum [gdb_get_line_number "printf(\"Hello from vforked-prog" ${src
file2}] |
| 418 set test "continue to bp" |
| 419 gdb_test_multiple "continue" $test { |
| 420 » -re ".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$
gdb_prompt " { |
| 421 » pass $test |
| 422 » } |
| 423 } |
| 424 } else { |
| 425 set test "continue to child exit" |
| 426 gdb_test_multiple "continue" $test { |
| 427 » -re "exited normally.*$gdb_prompt " { |
| 428 » pass $test |
| 429 » } |
| 430 } |
| 431 } |
| 432 |
| 433 set test "vfork relation no longer appears in info inferiors" |
| 434 gdb_test_multiple "info inferiors" $test { |
| 435 -re "is vfork child of inferior 1.*$gdb_prompt $" { |
| 436 » fail $test |
| 437 } |
| 438 -re "is vfork parent of inferior 2.*$gdb_prompt $" { |
| 439 » fail $test |
| 440 } |
| 441 -re "$gdb_prompt $" { |
| 442 » pass $test |
| 443 } |
| 444 } |
| 445 }} |
| 446 |
| 447 proc do_vfork_and_follow_parent_tests {} { |
| 448 global gdb_prompt |
| 342 | 449 |
| 343 # Try following the parent process by stepping through a call to | 450 # Try following the parent process by stepping through a call to |
| 344 # vfork. Do this without catchpoints. | 451 # vfork. Do this without catchpoints. |
| 345 if [runto_main] then { vfork_parent_follow_through_step } | 452 vfork_parent_follow_through_step |
| 346 | 453 |
| 347 # Try following the parent process by setting a breakpoint on the | 454 # Try following the parent process by setting a breakpoint on the |
| 348 # other side of a vfork, and running to that point. Do this | 455 # other side of a vfork, and running to that point. Do this |
| 349 # without catchpoints. | 456 # without catchpoints. |
| 350 if [runto_main] then { vfork_parent_follow_to_bp } | 457 vfork_parent_follow_to_bp |
| 351 | 458 |
| 459 # Try catching a vfork, and stepping out to the parent. |
| 460 # |
| 461 tcatch_vfork_then_parent_follow |
| 462 } |
| 463 |
| 464 proc do_vfork_and_follow_child_tests_exec {} { |
| 352 # Try following the child process by just continuing through the | 465 # Try following the child process by just continuing through the |
| 353 # vfork, and letting the parent's breakpoint on "main" be auto- | 466 # vfork, and letting the parent's breakpoint on "main" be auto- |
| 354 # magically reset in the child. | 467 # magically reset in the child. |
| 355 # | 468 # |
| 356 if [runto_main] then { vfork_and_exec_child_follow_to_main_bp } | 469 vfork_and_exec_child_follow_to_main_bp |
| 357 | 470 |
| 358 # Try following the child process by stepping through a call to | 471 # Try following the child process by stepping through a call to |
| 359 # vfork. The child also executes an exec. Since the child cannot | 472 # vfork. The child also executes an exec. Since the child cannot |
| 360 # be debugged until after it has exec'd, and since there's a bp on | 473 # be debugged until after it has exec'd, and since there's a bp on |
| 361 # "main" in the parent, and since the bp's for the parent are | 474 # "main" in the parent, and since the bp's for the parent are |
| 362 # recomputed in the exec'd child, the step through a vfork should | 475 # recomputed in the exec'd child, the step through a vfork should |
| 363 # land us in the "main" for the exec'd child, too. | 476 # land us in the "main" for the exec'd child, too. |
| 364 # | 477 # |
| 365 if [runto_main] then { vfork_and_exec_child_follow_through_step } | 478 vfork_and_exec_child_follow_through_step |
| 366 | |
| 367 # Try catching a vfork, and stepping out to the parent. | |
| 368 # | |
| 369 if [runto_main] then { tcatch_vfork_then_parent_follow } | |
| 370 | 479 |
| 371 # Try catching a vfork, and stepping out to the child. | 480 # Try catching a vfork, and stepping out to the child. |
| 372 # | 481 # |
| 373 if [runto_main] then { tcatch_vfork_then_child_follow } | 482 tcatch_vfork_then_child_follow_exec |
| 374 | 483 |
| 375 # Test the ability to follow both child and parent of a vfork. Do | 484 # Test the ability to follow both child and parent of a vfork. Do |
| 376 # this without catchpoints. | 485 # this without catchpoints. |
| 377 # ??rehrauer: NYI. Will add testpoints here when implemented. | 486 # ??rehrauer: NYI. Will add testpoints here when implemented. |
| 378 # | 487 # |
| 379 | 488 |
| 380 # Test the ability to have the debugger ask the user at vfork-time | 489 # Test the ability to have the debugger ask the user at vfork-time |
| 381 # whether to follow the parent, child or both. Do this without | 490 # whether to follow the parent, child or both. Do this without |
| 382 # catchpoints. | 491 # catchpoints. |
| 383 # ??rehrauer: NYI. Will add testpoints here when implemented. | 492 # ??rehrauer: NYI. Will add testpoints here when implemented. |
| 384 # | 493 # |
| 494 |
| 495 # Step over a vfork in the child, do "info inferiors" and check the |
| 496 # parent/child relation is displayed. Run the child over the exec, |
| 497 # and confirm the relation is no longer displayed in "info |
| 498 # inferiors". |
| 499 # |
| 500 vfork_relations_in_info_inferiors "exec" |
| 385 } | 501 } |
| 386 | 502 |
| 387 # Start with a fresh gdb | 503 proc do_vfork_and_follow_child_tests_exit {} { |
| 504 # Try following the child process by just continuing through the |
| 505 # vfork, and letting the child exit. |
| 506 # |
| 507 vfork_child_follow_to_exit |
| 388 | 508 |
| 389 gdb_exit | 509 # Try catching a vfork, and stepping out to the child. |
| 390 gdb_start | 510 # |
| 391 gdb_reinitialize_dir $srcdir/$subdir | 511 tcatch_vfork_then_child_follow_exit |
| 392 gdb_load ${binfile} | |
| 393 | 512 |
| 394 # The "Detaching..." and "Attaching..." messages may be hidden by | 513 # Step over a vfork in the child, do "info inferiors" and check the |
| 395 # default. | 514 # parent/child relation is displayed. Run the child to completion, |
| 396 gdb_test_no_output "set verbose" | 515 # and confirm the relation is no longer displayed in "info |
| 516 # inferiors". |
| 517 # |
| 518 vfork_relations_in_info_inferiors "exit" |
| 519 } |
| 397 | 520 |
| 398 # This is a test of gdb's ability to follow the parent or child | 521 with_test_prefix "check vfork support" { |
| 399 # of a Unix vfork() system call. (The child will subsequently | 522 # Check that vfork catchpoints are supported, as an indicator for |
| 400 # call a variant of a Unix exec() system call.) | 523 # whether vfork-following is supported. |
| 401 # | 524 check_vfork_catchpoints |
| 402 do_vfork_and_exec_tests | 525 } |
| 526 |
| 527 # Follow parent and follow child vfork tests with a child that execs. |
| 528 with_test_prefix "exec" { |
| 529 # These are tests of gdb's ability to follow the parent of a Unix |
| 530 # vfork system call. The child will subsequently call a variant |
| 531 # of the Unix exec system call. |
| 532 do_vfork_and_follow_parent_tests |
| 533 |
| 534 # These are tests of gdb's ability to follow the child of a Unix |
| 535 # vfork system call. The child will subsequently call a variant |
| 536 # of a Unix exec system call. |
| 537 # |
| 538 do_vfork_and_follow_child_tests_exec |
| 539 } |
| 540 |
| 541 # Switch to test the case of the child exiting. We can't use |
| 542 # standard_testfile here because we don't want to overwrite the binary |
| 543 # of the previous tests. |
| 544 set testfile "foll-vfork-exit" |
| 545 set srcfile ${testfile}.c |
| 546 set binfile [standard_output_file ${testfile}] |
| 547 |
| 548 if {[build_executable $testfile.exp $testfile $srcfile] == -1} { |
| 549 untested "failed to build $testfile" |
| 550 return |
| 551 } |
| 552 |
| 553 # Follow parent and follow child vfork tests with a child that exits. |
| 554 with_test_prefix "exit" { |
| 555 # These are tests of gdb's ability to follow the parent of a Unix |
| 556 # vfork system call. The child will subsequently exit. |
| 557 do_vfork_and_follow_parent_tests |
| 558 |
| 559 # These are tests of gdb's ability to follow the child of a Unix |
| 560 # vfork system call. The child will subsequently exit. |
| 561 # |
| 562 do_vfork_and_follow_child_tests_exit |
| 563 } |
| 403 | 564 |
| 404 set timeout $oldtimeout | 565 set timeout $oldtimeout |
| 405 return 0 | 566 return 0 |
| OLD | NEW |