2012-11-02 Pedro Alves <palves@redhat.com>

* gdb.base/foll-vfork-exit.c: New file.
	* gdb.base/foll-vfork.exp (top level): New file-describing
	comment.
	(vfork_child_follow_to_exit): New procedure.
	(tcatch_vfork_then_child_follow): Rename as ...
	(tcatch_vfork_then_child_follow_exec): ... this.
	(tcatch_vfork_then_child_follow_exit): New procedure.
	(do_vfork_and_follow_parent_tests): New procedure, factored out
	from do_vfork_and_exec_tests.
	(do_vfork_and_follow_child_tests_exec): Ditto.
	(do_vfork_and_exec_tests): Delete.
	(do_vfork_and_follow_child_tests_exit): New procedure.
	(top level): Run tests with both the program that has the vfork
	child execing, and the program has the vfork child exiting.
This commit is contained in:
Pedro Alves 2012-11-02 18:10:29 +00:00
parent 1e35b1a94e
commit 71ce889da9
3 changed files with 195 additions and 15 deletions

View File

@ -1,3 +1,20 @@
2012-11-02 Pedro Alves <palves@redhat.com>
* gdb.base/foll-vfork-exit.c: New file.
* gdb.base/foll-vfork.exp (top level): New file-describing
comment.
(vfork_child_follow_to_exit): New procedure.
(tcatch_vfork_then_child_follow): Rename as ...
(tcatch_vfork_then_child_follow_exec): ... this.
(tcatch_vfork_then_child_follow_exit): New procedure.
(do_vfork_and_follow_parent_tests): New procedure, factored out
from do_vfork_and_exec_tests.
(do_vfork_and_follow_child_tests_exec): Ditto.
(do_vfork_and_exec_tests): Delete.
(do_vfork_and_follow_child_tests_exit): New procedure.
(top level): Run tests with both the program that has the vfork
child execing, and the program has the vfork child exiting.
2012-11-02 Pedro Alves <palves@redhat.com>
* gdb.base/foll-vfork.exp (setup_gdb): New procedure.

View File

@ -0,0 +1,38 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 1997, 1999, 2007-2012 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <unistd.h>
int
main ()
{
int pid;
pid = vfork ();
if (pid == 0)
{
printf ("I'm the child!\n");
_exit (0);
}
else
{
printf ("I'm the proud parent of child #%d!\n", pid);
}
return 0;
}

View File

@ -13,6 +13,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Various tests of gdb's ability to follow the parent or child of a
# Unix vfork system call. A vfork parent is blocked until the child
# either execs or exits --- since those events take somewhat different
# code paths in GDB, both variants are exercised.
if { [is_remote target] || ![isnative] } then {
continue
}
@ -148,6 +153,31 @@ proc vfork_parent_follow_to_bp {} {
exec sleep 1
}}
proc vfork_child_follow_to_exit {} {
with_test_prefix "vfork child follow, to exit" {
global gdb_prompt
setup_gdb
gdb_test_no_output "set follow-fork child"
set test "continue to child exit"
gdb_test_multiple "continue" $test {
-re "Couldn't get registers.*$gdb_prompt " {
setup_kfail "gdb/14766" *-*-*
fail "$test"
}
-re "Attaching after.* vfork to.*Detaching vfork parent .* after child exit.*$gdb_prompt " {
pass $test
}
}
# The parent has been detached; allow time for any output it might
# generate to arrive, so that output doesn't get confused with
# any gdb_expected debugger output from a subsequent testpoint.
#
exec sleep 1
}}
proc vfork_and_exec_child_follow_to_main_bp {} {
with_test_prefix "vfork and exec child follow, to main bp" {
global gdb_prompt
@ -267,7 +297,7 @@ proc tcatch_vfork_then_parent_follow {} {
exec sleep 1
}}
proc tcatch_vfork_then_child_follow {} {
proc tcatch_vfork_then_child_follow_exec {} {
with_test_prefix "vfork child follow, finish after tcatch vfork" {
global gdb_prompt
global srcfile
@ -314,12 +344,56 @@ proc tcatch_vfork_then_child_follow {} {
exec sleep 1
}}
proc do_vfork_and_exec_tests {} {
proc tcatch_vfork_then_child_follow_exit {} {
with_test_prefix "vfork child follow, finish after tcatch vfork" {
global gdb_prompt
global srcfile
# Check that vfork catchpoints are supported, as an indicator for whether
# vfork-following is supported.
check_vfork_catchpoints
setup_gdb
gdb_test_no_output "set follow-fork child"
gdb_test "tcatch vfork" "Catchpoint .*(vfork).*"
# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
# stop you in "_vfork".
set test "continue to vfork"
gdb_test_multiple "continue" $test {
-re "vfork \\(\\) at .*$gdb_prompt $" {
pass $test
}
-re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " {
pass $test
}
}
set test "finish"
gdb_test_multiple "finish" $test {
-re "Couldn't get registers.*$gdb_prompt " {
setup_kfail "gdb/14766" *-*-*
fail "$test "
}
-re "Run till exit from.*vfork.*exited normally.*$gdb_prompt " {
setup_kfail "gdb/14762" *-*-*
fail $test
}
-re "Run till exit from.*vfork.*pid = vfork \\(\\).*$gdb_prompt " {
pass $test
}
-re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " {
send_gdb "finish\n"
exp_continue
}
}
# The parent has been detached; allow time for any output it might
# generate to arrive, so that output doesn't get confused with
# any expected debugger output from a subsequent testpoint.
#
exec sleep 1
}}
proc do_vfork_and_follow_parent_tests {} {
global gdb_prompt
# Try following the parent process by stepping through a call to
# vfork. Do this without catchpoints.
@ -330,6 +404,12 @@ proc do_vfork_and_exec_tests {} {
# without catchpoints.
vfork_parent_follow_to_bp
# Try catching a vfork, and stepping out to the parent.
#
tcatch_vfork_then_parent_follow
}
proc do_vfork_and_follow_child_tests_exec {} {
# Try following the child process by just continuing through the
# vfork, and letting the parent's breakpoint on "main" be auto-
# magically reset in the child.
@ -345,13 +425,9 @@ proc do_vfork_and_exec_tests {} {
#
vfork_and_exec_child_follow_through_step
# Try catching a vfork, and stepping out to the parent.
#
tcatch_vfork_then_parent_follow
# Try catching a vfork, and stepping out to the child.
#
tcatch_vfork_then_child_follow
tcatch_vfork_then_child_follow_exec
# Test the ability to follow both child and parent of a vfork. Do
# this without catchpoints.
@ -365,11 +441,60 @@ proc do_vfork_and_exec_tests {} {
#
}
# This is a test of gdb's ability to follow the parent or child
# of a Unix vfork() system call. (The child will subsequently
# call a variant of a Unix exec() system call.)
#
do_vfork_and_exec_tests
proc do_vfork_and_follow_child_tests_exit {} {
# Try following the child process by just continuing through the
# vfork, and letting the child exit.
#
vfork_child_follow_to_exit
# Try catching a vfork, and stepping out to the child.
#
tcatch_vfork_then_child_follow_exit
}
with_test_prefix "check vfork support" {
# Check that vfork catchpoints are supported, as an indicator for
# whether vfork-following is supported.
check_vfork_catchpoints
}
# Follow parent and follow child vfork tests with a child that execs.
with_test_prefix "exec" {
# These are tests of gdb's ability to follow the parent of a Unix
# vfork system call. The child will subsequently call a variant
# of the Unix exec system call.
do_vfork_and_follow_parent_tests
# These are tests of gdb's ability to follow the child of a Unix
# vfork system call. The child will subsequently call a variant
# of a Unix exec system call.
#
do_vfork_and_follow_child_tests_exec
}
# Switch to test the case of the child exiting. We can't use
# standard_testfile here because we don't want to overwrite the binary
# of the previous tests.
set testfile "foll-vfork-exit"
set srcfile ${testfile}.c
set binfile [standard_output_file ${testfile}]
if {[build_executable $testfile.exp $testfile $srcfile] == -1} {
untested "failed to build $testfile"
return
}
# Follow parent and follow child vfork tests with a child that exits.
with_test_prefix "exit" {
# These are tests of gdb's ability to follow the parent of a Unix
# vfork system call. The child will subsequently exit.
do_vfork_and_follow_parent_tests
# These are tests of gdb's ability to follow the child of a Unix
# vfork system call. The child will subsequently exit.
#
do_vfork_and_follow_child_tests_exit
}
set timeout $oldtimeout
return 0