This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 7/8] foll-vfork.exp: Also test following vfork when the child exits.


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  <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.
---
 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 <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 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 <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
 }
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]