1 # Copyright 1997, 1999, 2007-2012 Free Software Foundation, Inc.
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.
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.
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/>.
16 if { [is_remote target] || ![isnative] } then {
20 # Until "set follow-fork-mode" and "catch vfork" are implemented on
23 if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
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
31 if [istarget "hppa*-hp-hpux10.20"] then {
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.
38 ##if [istarget "hppa2.0w-hp-hpux*"] {
39 ## warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed."
45 if {[build_executable $testfile.exp $testfile $srcfile {debug}] == -1} {
46 untested "failed to compile $testfile"
50 set testfile2 "vforked-prog"
51 set srcfile2 ${testfile2}.c
53 if {[build_executable $testfile.exp $testfile2 $srcfile2 {debug}] == -1} {
54 untested "failed to compile $testfile2"
58 # A few of these tests require a little more time than the standard
60 set oldtimeout $timeout
61 set timeout [expr "$timeout + 10"]
63 proc check_vfork_catchpoints {} {
65 global has_vfork_catchpoints
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"
74 -re ".*Catchpoint.*$gdb_prompt $" {
75 set has_vfork_catchpoints 1
76 pass "continue to first vfork catchpoint"
80 if {$has_vfork_catchpoints == 0} {
81 unsupported "vfork catchpoints"
86 proc vfork_parent_follow_through_step {} {
87 with_test_prefix "vfork parent follow, through step" {
90 gdb_test_no_output "set follow-fork parent"
93 gdb_test_multiple "next" $test {
94 -re "Detaching after fork from.*if \\(pid == 0\\).*$gdb_prompt " {
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.
105 proc vfork_parent_follow_to_bp {} {
106 with_test_prefix "vfork parent follow, to bp" {
110 gdb_test_no_output "set follow-fork parent"
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"
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 " {
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.
128 # Kill child and reload symbols.
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. $" {
141 gdb_test_multiple "" "loading symbols" {
142 -re "Reading symbols from.*$gdb_prompt $" {
146 -re ".*gdb_prompt $" {
150 -re ".*$gdb_prompt $" {
155 proc vfork_and_exec_child_follow_to_main_bp {} {
156 with_test_prefix "vfork and exec child follow, to main bp" {
160 gdb_test_no_output "set follow-fork child"
162 set linenum [gdb_get_line_number "printf(\"Hello from vforked-prog" ${srcfile2}]
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 " {
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.
176 # Explicitly kill this child, or a subsequent rerun actually runs
177 # the exec'd child, not the original program...
181 proc vfork_and_exec_child_follow_through_step {} {
182 with_test_prefix "vfork and exec child follow, through step" {
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
196 verbose "vfork child-following next test ignored for pre-HP/UX-10.30 targets."
200 gdb_test_no_output "set follow-fork child"
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
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 " {
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
220 gdb_test_multiple "next" $test {
221 -re "Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
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.
232 # Explicitly kill this child, or a subsequent rerun actually runs
233 # the exec'd child, not the original program...
237 proc tcatch_vfork_then_parent_follow {} {
238 with_test_prefix "vfork parent follow, finish after tcatch vfork" {
242 gdb_test_no_output "set follow-fork parent"
244 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*"
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 " {
253 -re "vfork \\(\\) at.*$gdb_prompt " {
258 set linenum [gdb_get_line_number "pid = vfork ();"]
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 " {
264 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
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.
276 proc tcatch_vfork_then_child_follow {} {
277 with_test_prefix "vfork child follow, finish after tcatch vfork" {
282 gdb_test_no_output "set follow-fork child"
284 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*"
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 $" {
293 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " {
298 set linenum1 [gdb_get_line_number "pid = vfork ();"]
299 set linenum2 [gdb_get_line_number "printf(\"Hello from vforked-prog" ${srcfile2}]
302 gdb_test_multiple "finish" $test {
303 -re "Run till exit from.*vfork.*${srcfile}:${linenum1}.*$gdb_prompt " {
306 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
310 -re "Run till exit from.*vfork.*${srcfile2}:${linenum2}.*$gdb_prompt " {
311 pass "$test (followed exec)"
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.
321 proc do_vfork_and_exec_tests {} {
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 }
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 }
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 }
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.
341 if [runto_main] then { vfork_and_exec_child_follow_to_main_bp }
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.
350 if [runto_main] then { vfork_and_exec_child_follow_through_step }
352 # Try catching a vfork, and stepping out to the parent.
354 if [runto_main] then { tcatch_vfork_then_parent_follow }
356 # Try catching a vfork, and stepping out to the child.
358 if [runto_main] then { tcatch_vfork_then_child_follow }
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.
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
368 # ??rehrauer: NYI. Will add testpoints here when implemented.
372 # Start with a fresh gdb
373 clean_restart $testfile
375 # The "Detaching..." and "Attaching..." messages may be hidden by
377 gdb_test_no_output "set verbose"
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.)
383 do_vfork_and_exec_tests
385 set timeout $oldtimeout