From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28970 invoked by alias); 25 Oct 2012 17:42:53 -0000 Received: (qmail 28933 invoked by uid 22791); 25 Oct 2012 17:42:52 -0000 X-SWARE-Spam-Status: No, hits=-8.0 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 25 Oct 2012 17:42:43 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q9PHggeU013326 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 25 Oct 2012 13:42:42 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q9PHgeBH015984 for ; Thu, 25 Oct 2012 13:42:41 -0400 Subject: [PATCH 7/8] foll-vfork.exp: Also test following vfork when the child exits. To: gdb-patches@sourceware.org From: Pedro Alves Date: Thu, 25 Oct 2012 17:42:00 -0000 Message-ID: <20121025174240.13324.88096.stgit@brno.lan> In-Reply-To: <20121025174002.13324.8164.stgit@brno.lan> References: <20121025174002.13324.8164.stgit@brno.lan> User-Agent: StGit/0.16 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-10/txt/msg00510.txt.bz2 foll-vfork.exp currently has tests for both following the vfork parent, and the vfork child. However, the vfork shared region is done with when either the child execs, or exits, and the tests only test the exec variant. These events are handled with similar yet not-quite-the-same code paths in GDB, so it's useful to add that vector to the test matrix as well. (gdb/14766 is a case of a bug on the exit path only. gdb/14762 is exposed by making the tests cover the whole testing matrix.) The patch implements that by adding a new test source based on foll-vfork.c that has been adjusted to have the child _exit instead of exec. The follow-parent tests can all run with either the exit or exec variant, using the same tcl procedure even (with_test_prefix is used to distinguish the variants in gdb.sum). Some of the follow-child tests can too, while others cannot -- the one's that can't get special tcl procedures for each exec/exit variant. (I had originally developed this as a separate new .exp test file, based on foll-vfork.exp, until I decided that it was better to merge them.) (This kfails both gdb/14762 and gdb/14766. The gdb/14762 kfail is actually masked by gdb/14766. The next patch fixes gdb/14766, thus exposing the gdb/14762 kfail...) gdb/testsuite/ 2012-10-25 Pedro Alves * 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. --- gdb/testsuite/gdb.base/foll-vfork-exit.c | 38 +++++++ gdb/testsuite/gdb.base/foll-vfork.exp | 155 +++++++++++++++++++++++++++--- 2 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 gdb/testsuite/gdb.base/foll-vfork-exit.c 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 . */ + +#include +#include + +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 31477ef..ca04cdc 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 . +# 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 } @@ -146,6 +151,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 @@ -265,7 +295,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 @@ -312,12 +342,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. @@ -328,6 +402,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. @@ -343,13 +423,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. @@ -363,11 +439,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