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