diff options
author | Pedro Alves <palves@redhat.com> | 2012-11-02 18:10:29 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-11-02 18:10:29 +0000 |
commit | 71ce889da907b11ec88efa3ddc93ee1f0371f8e9 (patch) | |
tree | 99df49bba46623161516f369601149d15d26e3f4 | |
parent | 1e35b1a94e55f79e3ae629dd2237224f3e230867 (diff) | |
download | gdb-71ce889da907b11ec88efa3ddc93ee1f0371f8e9.zip gdb-71ce889da907b11ec88efa3ddc93ee1f0371f8e9.tar.gz gdb-71ce889da907b11ec88efa3ddc93ee1f0371f8e9.tar.bz2 |
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.
-rw-r--r-- | gdb/testsuite/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/foll-vfork-exit.c | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/foll-vfork.exp | 155 |
3 files changed, 195 insertions, 15 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ea7f891..e7e42d8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,22 @@ 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. (check_vfork_catchpoints, vfork_parent_follow_through_step) (vfork_parent_follow_to_bp): Call it. diff --git a/gdb/testsuite/gdb.base/foll-vfork-exit.c b/gdb/testsuite/gdb.base/foll-vfork-exit.c new file mode 100644 index 0000000..6aa8a5c --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-vfork-exit.c @@ -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; +} diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index 68934e7..9515d16 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -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 + + 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 +}} - # Check that vfork catchpoints are supported, as an indicator for whether - # vfork-following is supported. - check_vfork_catchpoints +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 |