1 # Copyright
1997-2019 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 # 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.
21 # Until "set follow-fork-mode" and "catch vfork" are implemented on
24 if {![istarget "*-linux*"]} then {
30 set compile_options debug
32 if {[build_executable $testfile.exp $testfile $srcfile $compile_options] == -1} {
33 untested "failed to compile main testcase"
37 set testfile2 "vforked-prog"
38 set srcfile2 ${testfile2}.c
40 if {[build_executable $testfile.exp $testfile2 $srcfile2 $compile_options] == -1} {
41 untested "failed to compile secondary testcase"
45 # A few of these tests require a little more time than the standard
47 set oldtimeout $timeout
48 set timeout [expr "$timeout + 10"]
50 # Start with a fresh GDB, with verbosity enabled, and run to main. On
51 # error, behave as "return", so we don't try to
continue testing with
54 global testfile srcfile
56 clean_restart $testfile
62 set tbreak_line
[gdb_get_line_number
" VFORK " $srcfile]
63 gdb_test
"tbreak ${tbreak_line}"
64 gdb_continue_to_breakpoint
".*"
67 proc check_vfork_catchpoints
{} {
69 global has_vfork_catchpoints
73 # Verify that the
system supports
"catch vfork".
74 gdb_test
"catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork catchpoint"
75 set has_vfork_catchpoints
0
76 gdb_test_multiple
"continue" "continue to first vfork catchpoint" {
77 -re
".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" {
78 unsupported
"continue to first vfork catchpoint"
80 -re
".*Catchpoint.*$gdb_prompt $" {
81 set has_vfork_catchpoints
1
82 pass
"continue to first vfork catchpoint"
86 if {$has_vfork_catchpoints
== 0} {
87 unsupported
"vfork catchpoints"
92 proc vfork_parent_follow_through_step
{} {
93 with_test_prefix
"vfork parent follow, through step" {
98 gdb_test_no_output
"set follow-fork parent"
101 gdb_test_multiple
"next" $test {
102 -re
"\\\[Detaching after vfork from.*if \\(pid == 0\\).*$gdb_prompt " {
106 # The child has been detached
; allow time
for any output it might
107 # generate to arrive
, so that output doesn
't get confused with
108 # any gdb_expected debugger output from a subsequent testpoint.
113 proc vfork_parent_follow_to_bp {} {
114 with_test_prefix "vfork parent follow, to bp" {
120 gdb_test_no_output "set follow-fork parent"
122 set bp_location [gdb_get_line_number "printf (\"I'm the proud parent of child
"]
123 gdb_test
"break ${srcfile}:${bp_location}" ".*" "break, vfork to bp"
125 set test
"continue to bp"
126 gdb_test_multiple
"continue" $test {
127 -re
".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*$gdb_prompt " {
131 # The child has been detached
; allow time
for any output it might
132 # generate to arrive
, so that output doesn
't get confused with
133 # any expected debugger output from a subsequent testpoint.
138 proc vfork_child_follow_to_exit {} {
139 with_test_prefix "vfork child follow, to exit" {
144 gdb_test_no_output "set follow-fork child"
146 set test "continue to child exit"
147 gdb_test_multiple "continue" $test {
148 -re "Couldn't
get registers.
*$gdb_prompt
" {
152 -re
"\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent .* after child exit.*$gdb_prompt " {
156 # The parent has been detached
; allow time
for any output it might
157 # generate to arrive
, so that output doesn
't get confused with
158 # any gdb_expected debugger output from a subsequent testpoint.
163 proc vfork_and_exec_child_follow_to_main_bp {} {
164 with_test_prefix "vfork and exec child follow, to main bp" {
170 gdb_test_no_output "set follow-fork child"
172 set linenum [gdb_get_line_number "printf(\"Hello from vforked-prog" ${srcfile2}]
174 set test "continue to bp"
175 gdb_test_multiple "continue" $test {
176 -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " {
180 # The parent has been detached; allow time for any output it might
181 # generate to arrive, so that output doesn't
get confused with
182 #
any gdb_expected debugger output from a subsequent testpoint.
187 proc vfork_and_exec_child_follow_through_step
{} {
188 with_test_prefix
"vfork and exec child follow, through step" {
194 gdb_test_no_output
"set follow-fork child"
196 set test
"step over vfork"
198 # The ideal support is to be able to debug the child even
199 # before it execs. Thus
, "next" lands on the next line after
201 gdb_test_multiple
"next" $test {
202 -re
"\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
206 # The parent has been detached
; allow time
for any output it might
207 # generate to arrive
, so that output doesn
't get confused with
208 # any expected debugger output from a subsequent testpoint.
213 proc continue_to_vfork {} {
216 # A vfork catchpoint may stop in either "vfork" or "_vfork".
217 set test "continue to vfork"
218 gdb_test_multiple "continue" $test {
219 -re "vfork \\(\\) at .*$gdb_prompt $" {
222 -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " {
228 proc tcatch_vfork_then_parent_follow {} {
229 with_test_prefix "vfork parent follow, finish after tcatch vfork" {
235 gdb_test_no_output "set follow-fork parent"
237 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*"
241 set linenum [gdb_get_line_number "pid = vfork ();"]
243 gdb_test_multiple "finish" $test {
244 -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:${linenum}.*$gdb_prompt " {
247 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
252 # The child has been detached; allow time for any output it might
253 # generate to arrive, so that output doesn't
get confused with
254 #
any expected debugger output from a subsequent testpoint.
259 proc tcatch_vfork_then_child_follow_exec
{} {
260 with_test_prefix
"vfork child follow, finish after tcatch vfork" {
267 gdb_test_no_output
"set follow-fork child"
269 gdb_test
"tcatch vfork" "Catchpoint .*(vfork).*"
273 set linenum1
[gdb_get_line_number
"pid = vfork ();"]
274 set linenum2
[gdb_get_line_number
"printf(\"Hello from vforked-prog" ${srcfile2}]
277 gdb_test_multiple
"finish" $test {
278 -re
"Run till exit from.*vfork.*${srcfile}:${linenum1}.*$gdb_prompt " {
281 -re
"Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
285 -re
"Run till exit from.*vfork.*${srcfile2}:${linenum2}.*$gdb_prompt " {
286 pass
"$test (followed exec)"
289 # The parent has been detached
; allow time
for any output it might
290 # generate to arrive
, so that output doesn
't get confused with
291 # any expected debugger output from a subsequent testpoint.
296 proc tcatch_vfork_then_child_follow_exit {} {
297 with_test_prefix "vfork child follow, finish after tcatch vfork" {
303 gdb_test_no_output "set follow-fork child"
305 gdb_test "tcatch vfork" "Catchpoint .*(vfork).*"
310 gdb_test_multiple "finish" $test {
311 -re "Run till exit from.*vfork.*exited normally.*$gdb_prompt " {
312 setup_kfail "gdb/14762" *-*-*
315 -re "Run till exit from.*vfork.*pid = vfork \\(\\).*$gdb_prompt " {
318 -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
323 # The parent has been detached; allow time for any output it might
324 # generate to arrive, so that output doesn't
get confused with
325 #
any expected debugger output from a subsequent testpoint.
330 proc vfork_relations_in_info_inferiors
{ variant
} {
331 with_test_prefix
"vfork relations in info inferiors" {
336 gdb_test_no_output
"set follow-fork child"
338 set test
"step over vfork"
339 gdb_test_multiple
"next" $test {
340 -re
"\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
345 gdb_test
"info inferiors" \
346 ".*is vfork parent of inferior 2.*is vfork child of inferior 1" \
347 "info inferiors shows vfork parent/child relation"
349 if { $variant
== "exec" } {
352 set linenum [gdb_get_line_number
"printf(\"Hello from vforked-prog" ${srcfile2}]
353 set test
"continue to bp"
354 gdb_test_multiple
"continue" $test {
355 -re
".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " {
360 set test
"continue to child exit"
361 gdb_test_multiple
"continue" $test {
362 -re
"exited normally.*$gdb_prompt " {
368 set test
"vfork relation no longer appears in info inferiors"
369 gdb_test_multiple
"info inferiors" $test {
370 -re
"is vfork child of inferior 1.*$gdb_prompt $" {
373 -re
"is vfork parent of inferior 2.*$gdb_prompt $" {
376 -re
"$gdb_prompt $" {
382 proc do_vfork_and_follow_parent_tests
{} {
385 # Try following the parent process by stepping through a
call to
386 # vfork.
Do this without catchpoints.
387 vfork_parent_follow_through_step
389 # Try following the parent process by setting a breakpoint
on the
390 # other side of a vfork
, and running to that point.
Do this
391 # without catchpoints.
392 vfork_parent_follow_to_bp
394 # Try catching a vfork
, and stepping out to the parent.
396 tcatch_vfork_then_parent_follow
399 proc do_vfork_and_follow_child_tests_exec
{} {
400 # Try following the child process by just continuing through the
401 # vfork
, and letting the parent
's breakpoint on "main" be auto-
402 # magically reset in the child.
404 vfork_and_exec_child_follow_to_main_bp
406 # Try following the child process by stepping through a call to
407 # vfork. The child also executes an exec. Since the child cannot
408 # be debugged until after it has exec'd
, and since there
's a bp on
409 # "main" in the parent, and since the bp's
for the parent are
410 # recomputed in the exec
'd child, the step through a vfork should
411 # land us in the "main" for the exec'd child
, too.
413 vfork_and_exec_child_follow_through_step
415 # Try catching a vfork
, and stepping out to the child.
417 tcatch_vfork_then_child_follow_exec
419 # Test the ability to follow both child and parent of a vfork.
Do
420 # this without catchpoints.
421 # ??rehrauer
: NYI. Will add testpoints here when implemented.
424 # Test the ability to have the debugger ask the user at vfork
-time
425 # whether to follow the parent
, child or both.
Do this without
427 # ??rehrauer
: NYI. Will add testpoints here when implemented.
430 # Step over a vfork in the child
, do "info inferiors" and check the
431 # parent
/child
relation is displayed. Run the child over the exec
,
432 # and confirm the
relation is no longer displayed in
"info
435 vfork_relations_in_info_inferiors
"exec"
438 proc do_vfork_and_follow_child_tests_exit
{} {
439 # Try following the child process by just continuing through the
440 # vfork
, and letting the child exit.
442 vfork_child_follow_to_exit
444 # Try catching a vfork
, and stepping out to the child.
446 tcatch_vfork_then_child_follow_exit
448 # Step over a vfork in the child
, do "info inferiors" and check the
449 # parent
/child
relation is displayed. Run the child to completion
,
450 # and confirm the
relation is no longer displayed in
"info
453 vfork_relations_in_info_inferiors
"exit"
456 with_test_prefix
"check vfork support" {
457 # Check that vfork catchpoints are supported
, as an indicator
for
458 # whether vfork
-following is supported.
459 check_vfork_catchpoints
462 # Follow parent and follow child vfork tests with a child that execs.
463 with_test_prefix
"exec" {
464 # These are tests of gdb
's ability to follow the parent of a Unix
465 # vfork system call. The child will subsequently call a variant
466 # of the Unix exec system call.
467 do_vfork_and_follow_parent_tests
469 # These are tests of gdb's ability to follow the child of a Unix
470 # vfork
system call. The child will subsequently
call a variant
471 # of a Unix exec
system call.
473 do_vfork_and_follow_child_tests_exec
476 #
Switch to test the case of the child exiting. We can
't use
477 # standard_testfile here because we don't want to overwrite the binary
478 # of the previous tests.
479 set testfile
"foll-vfork-exit"
480 set srcfile $
{testfile
}.c
481 set binfile
[standard_output_file $
{testfile
}]
483 if {[build_executable $testfile.exp $testfile $srcfile
] == -1} {
484 untested
"failed to build $testfile"
488 # Follow parent and follow child vfork tests with a child that exits.
489 with_test_prefix
"exit" {
490 # These are tests of gdb
's ability to follow the parent of a Unix
491 # vfork system call. The child will subsequently exit.
492 do_vfork_and_follow_parent_tests
494 # These are tests of gdb's ability to follow the child of a Unix
495 # vfork
system call. The child will subsequently exit.
497 do_vfork_and_follow_child_tests_exit
500 set timeout $oldtimeout