2012-11-02 Pedro Alves <palves@redhat.com>
authorPedro Alves <palves@redhat.com>
Fri, 2 Nov 2012 18:10:29 +0000 (18:10 +0000)
committerPedro Alves <palves@redhat.com>
Fri, 2 Nov 2012 18:10:29 +0000 (18:10 +0000)
* 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/ChangeLog
gdb/testsuite/gdb.base/foll-vfork-exit.c [new file with mode: 0644]
gdb/testsuite/gdb.base/foll-vfork.exp

index ea7f891..e7e42d8 100644 (file)
@@ -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 (file)
index 0000000..6aa8a5c
--- /dev/null
@@ -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;
+}
index 68934e7..9515d16 100644 (file)
 # 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