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 |