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]

[RFC] Support exec tracing on GNU/Linux and HP-UX


MontaVista's testing discovered some trouble with follow-fork.
There's tests for this in the testsuite, but they're currently not
run.  So the first thing this patch does is fix up foll-fork.exp
to work on native GNU/Linux systems.

There's also tests for vfork and exec tracing.  Vfork tracing is
currently supported in GDB but exec tracing is not, and the vfork
testcase requires exec tracing anyway.  So I turned on exec tracing
and removed some cruft that had built up since it was last used.

The user interface is the same as it was when this was originally
added on HP-UX long ago.  When GDB sees an exec event, it
automatically loads the new executable as the main symbol file.
This is a little disconcerting if you try to use "run" again
later, but otherwise seems pretty convenient.

Any comments?  Mark (or someone else), could you offer to test this
on HP-UX?  I suspect the tests will fail for cosmetic reasons due to
the changed messages but I hope exec tracing will generally work.

I see that the manual still says fork/vfork tracing only works on
HP-UX.  I shall update that separately.

Tested on x86_64-linux.

-- 
Daniel Jacobowitz
CodeSourcery

2007-10-19  Daniel Jacobowitz  <dan@codesourcery.com>

	* Makefile.in (symfile.o): Update.
	* NEWS: Mention exec tracing support.
	* inf-ttrace.c (inf_ttrace_wait): Return TARGET_WAITKIND_EXECD for
	exec events.
	* infcmd.c (kill_if_already_running, detach_command)
	(disconnect_command): Replace SOLIB_RESTART with no_shared_libraries.
	* infrun.c (MAY_FOLLOW_EXEC, may_follow_exec): Delete.
	(follow_exec): Do not check may_follow_exec.  Do not mourn and push
	targets.  Apply the sysroot path to the loaded executable.  Use
	no_shared_libraries.
	* linux-nat.c (linux_child_follow_fork): Print fork following
	messages if verbose.
	(kill_wait_callback): Kill again before waiting a second time.
	* symfile.c (symbol_file_clear): Replace SOLIB_RESTART with
	no_shared_libraries.

2007-10-19  Daniel Jacobowitz  <dan@codesourcery.com>

	* gdb.base/foll-exec.exp: Update header.  Skip on remote targets.
	Run on GNU/Linux.
	(do_exec_tests): Check for systems which do not support catchpoints.
	Do not match START.
	* gdb.base/foll-fork.exp: Update header.  Skip on remote targets.
	Run on GNU/Linux.  Enable verbose output.
	(check_fork_catchpoints): New.
	(explicit_fork_child_follow, catch_fork_child_follow)
	(tcatch_fork_parent_follow): Update expected messages.
	(do_fork_tests): Use check_fork_catchpoints.
	* gdb.base/foll-vfork.exp: Update header.  Skip on remote targets.
	Run on GNU/Linux.  Enable verbose output.
	(check_vfork_catchpoints): New.
	(vfork_parent_follow_to_bp, tcatch_vfork_then_child_follow): Update
	expected messages.
	(do_vfork_and_exec_tests): Use check_fork_catchpoints.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.945
diff -u -p -r1.945 Makefile.in
--- Makefile.in	15 Oct 2007 19:45:30 -0000	1.945
+++ Makefile.in	19 Oct 2007 17:33:27 -0000
@@ -2760,7 +2760,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
 	$(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \
 	$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
 	$(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \
-	$(parser_defs_h) $(varobj_h) $(elf_bfd_h)
+	$(parser_defs_h) $(varobj_h) $(elf_bfd_h) $(solib_h)
 symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
 	$(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \
 	$(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h)
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.243
diff -u -p -r1.243 NEWS
--- NEWS	15 Oct 2007 20:00:23 -0000	1.243
+++ NEWS	19 Oct 2007 17:33:28 -0000
@@ -15,6 +15,9 @@ and in inlined functions.
 * The GDB remote stub, gdbserver, now supports the AltiVec and SPE
 registers on PowerPC targets.
 
+* GDB on GNU/Linux and HP/UX can now debug through "exec" of a new
+process.
+
 *** Changes in GDB 6.7
 
 * Resolved 101 resource leaks, null pointer dereferences, etc. in gdb, 
Index: inf-ttrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ttrace.c,v
retrieving revision 1.24
diff -u -p -r1.24 inf-ttrace.c
--- inf-ttrace.c	18 Sep 2007 12:42:22 -0000	1.24
+++ inf-ttrace.c	19 Oct 2007 17:33:28 -0000
@@ -896,10 +896,6 @@ inf_ttrace_wait (ptid_t ptid, struct tar
 #endif
 
     case TTEVT_EXEC:
-      /* FIXME: kettenis/20051029: GDB doesn't really know how to deal
-	 with TARGET_WAITKIND_EXECD events yet.  So we make it look
-	 like a SIGTRAP instead.  */
-#if 0
       ourstatus->kind = TARGET_WAITKIND_EXECD;
       ourstatus->value.execd_pathname =
 	xmalloc (tts.tts_u.tts_exec.tts_pathlen + 1);
@@ -908,10 +904,6 @@ inf_ttrace_wait (ptid_t ptid, struct tar
 		  tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
 	perror_with_name (("ttrace"));
       ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
-#else
-      ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
-#endif
       break;
 
     case TTEVT_EXIT:
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.160
diff -u -p -r1.160 infcmd.c
--- infcmd.c	12 Oct 2007 15:32:50 -0000	1.160
+++ infcmd.c	19 Oct 2007 17:33:28 -0000
@@ -453,9 +453,7 @@ kill_if_already_running (int from_tty)
 Start it from the beginning? "))
 	error (_("Program not restarted."));
       target_kill ();
-#if defined(SOLIB_RESTART)
-      SOLIB_RESTART ();
-#endif
+      no_shared_libraries (NULL, from_tty);
       init_wait_for_inferior ();
     }
 }
@@ -1962,9 +1960,7 @@ detach_command (char *args, int from_tty
 {
   dont_repeat ();		/* Not for the faint of heart.  */
   target_detach (args, from_tty);
-#if defined(SOLIB_RESTART)
-  SOLIB_RESTART ();
-#endif
+  no_shared_libraries (NULL, from_tty);
   if (deprecated_detach_hook)
     deprecated_detach_hook ();
 }
@@ -1982,9 +1978,7 @@ disconnect_command (char *args, int from
 {
   dont_repeat ();		/* Not for the faint of heart */
   target_disconnect (args, from_tty);
-#if defined(SOLIB_RESTART)
-  SOLIB_RESTART ();
-#endif
+  no_shared_libraries (NULL, from_tty);
   if (deprecated_detach_hook)
     deprecated_detach_hook ();
 }
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.249
diff -u -p -r1.249 infrun.c
--- infrun.c	1 Oct 2007 00:17:58 -0000	1.249
+++ infrun.c	19 Oct 2007 17:33:28 -0000
@@ -105,15 +105,6 @@ int sync_execution = 0;
 
 static ptid_t previous_inferior_ptid;
 
-/* This is true for configurations that may follow through execl() and
-   similar functions.  At present this is only true for HP-UX native.  */
-
-#ifndef MAY_FOLLOW_EXEC
-#define MAY_FOLLOW_EXEC (0)
-#endif
-
-static int may_follow_exec = MAY_FOLLOW_EXEC;
-
 static int debug_infrun = 0;
 static void
 show_debug_infrun (struct ui_file *file, int from_tty,
@@ -352,9 +343,6 @@ follow_exec (int pid, char *execd_pathna
   int saved_pid = pid;
   struct target_ops *tgt;
 
-  if (!may_follow_exec)
-    return;
-
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
      momentary bp's, etc.
@@ -389,17 +377,20 @@ follow_exec (int pid, char *execd_pathna
   /* We've followed the inferior through an exec.  Therefore, the
      inferior has essentially been killed & reborn. */
 
-  /* First collect the run target in effect.  */
-  tgt = find_run_target ();
-  /* If we can't find one, things are in a very strange state...  */
-  if (tgt == NULL)
-    error (_("Could find run target to save before following exec"));
-
   gdb_flush (gdb_stdout);
-  target_mourn_inferior ();
-  inferior_ptid = pid_to_ptid (saved_pid);
+  generic_mourn_inferior ();
   /* Because mourn_inferior resets inferior_ptid. */
-  push_target (tgt);
+  inferior_ptid = pid_to_ptid (saved_pid);
+
+  if (gdb_sysroot && *gdb_sysroot)
+    {
+      char *name = alloca (strlen (gdb_sysroot)
+			    + strlen (execd_pathname)
+			    + 1);
+      strcpy (name, gdb_sysroot);
+      strcat (name, execd_pathname);
+      execd_pathname = name;
+    }
 
   /* That a.out is now the one to use. */
   exec_file_attach (execd_pathname, 0);
@@ -410,9 +401,7 @@ follow_exec (int pid, char *execd_pathna
   /* Reset the shared library package.  This ensures that we get
      a shlib event when the child reaches "_start", at which point
      the dld will have had a chance to initialize the child. */
-#if defined(SOLIB_RESTART)
-  SOLIB_RESTART ();
-#endif
+  no_shared_libraries (NULL, 0);
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #else
Index: linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.70
diff -u -p -r1.70 linux-nat.c
--- linux-nat.c	11 Oct 2007 19:35:29 -0000	1.70
+++ linux-nat.c	19 Oct 2007 17:33:28 -0000
@@ -383,7 +383,7 @@ linux_child_follow_fork (struct target_o
       /* Detach new forked process?  */
       if (detach_fork)
 	{
-	  if (debug_linux_nat)
+	  if (info_verbose || debug_linux_nat)
 	    {
 	      target_terminal_ours ();
 	      fprintf_filtered (gdb_stdlog,
@@ -468,7 +468,7 @@ linux_child_follow_fork (struct target_o
       /* Before detaching from the parent, remove all breakpoints from it. */
       remove_breakpoints ();
 
-      if (debug_linux_nat)
+      if (info_verbose || debug_linux_nat)
 	{
 	  target_terminal_ours ();
 	  fprintf_filtered (gdb_stdlog,
@@ -2352,11 +2352,18 @@ kill_wait_callback (struct lwp_info *lp,
       do
 	{
 	  pid = my_waitpid (GET_LWP (lp->ptid), NULL, __WCLONE);
-	  if (pid != (pid_t) -1 && debug_linux_nat)
+	  if (pid != (pid_t) -1)
 	    {
-	      fprintf_unfiltered (gdb_stdlog,
-				  "KWC: wait %s received unknown.\n",
-				  target_pid_to_str (lp->ptid));
+	      if (debug_linux_nat)
+		fprintf_unfiltered (gdb_stdlog,
+				    "KWC: wait %s received unknown.\n",
+				    target_pid_to_str (lp->ptid));
+	      /* The Linux kernel sometimes fails to kill a thread
+		 completely after PTRACE_KILL; that goes from the stop
+		 point in do_fork out to the one in
+		 get_signal_to_deliever and waits again.  So kill it
+		 again.  */
+	      kill_callback (lp, NULL);
 	    }
 	}
       while (pid == GET_LWP (lp->ptid));
@@ -2367,11 +2374,14 @@ kill_wait_callback (struct lwp_info *lp,
   do
     {
       pid = my_waitpid (GET_LWP (lp->ptid), NULL, 0);
-      if (pid != (pid_t) -1 && debug_linux_nat)
+      if (pid != (pid_t) -1)
 	{
-	  fprintf_unfiltered (gdb_stdlog,
-			      "KWC: wait %s received unk.\n",
-			      target_pid_to_str (lp->ptid));
+	  if (debug_linux_nat)
+	    fprintf_unfiltered (gdb_stdlog,
+				"KWC: wait %s received unk.\n",
+				target_pid_to_str (lp->ptid));
+	  /* See the call to kill_callback above.  */
+	  kill_callback (lp, NULL);
 	}
     }
   while (pid == GET_LWP (lp->ptid));
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.192
diff -u -p -r1.192 symfile.c
--- symfile.c	24 Sep 2007 21:48:29 -0000	1.192
+++ symfile.c	19 Oct 2007 17:33:29 -0000
@@ -52,6 +52,7 @@
 #include "parser-defs.h"
 #include "varobj.h"
 #include "elf-bfd.h"
+#include "solib.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -1219,9 +1220,7 @@ symbol_file_clear (int from_tty)
        storage has just been released, we'd better wipe the solib
        descriptors as well.
      */
-#if defined(SOLIB_RESTART)
-    SOLIB_RESTART ();
-#endif
+    no_shared_libraries (NULL, from_tty);
 
     symfile_objfile = NULL;
     if (from_tty)
Index: testsuite/gdb.base/foll-exec.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/foll-exec.exp,v
retrieving revision 1.5
diff -u -p -r1.5 foll-exec.exp
--- testsuite/gdb.base/foll-exec.exp	23 Aug 2007 18:14:16 -0000	1.5
+++ testsuite/gdb.base/foll-exec.exp	19 Oct 2007 17:33:29 -0000
@@ -11,16 +11,9 @@
 # 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/>.  */
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@prep.ai.mit.edu
-
-if $tracelevel then {
-	strace $tracelevel
-	}
-
-if { ![isnative] } then {
+if { [is_remote target] || ![isnative] } then {
     continue
 }
 
@@ -48,7 +41,7 @@ if  { [gdb_compile "${srcdir}/${subdir}/
 
 # Until "catch exec" is implemented on other targets...
 #
-if ![istarget "hppa*-hp-hpux*"] then {
+if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
     continue
 }
 
@@ -93,6 +86,33 @@ proc do_exec_tests {} {
      return
    }
 
+   # Verify that the system supports "catch exec".
+   gdb_test "catch exec" "Catchpoint \[0-9\]* \\(exec\\)" "insert first exec catchpoint"
+   set has_exec_catchpoints 0
+   gdb_test_multiple "continue" "continue to first exec catchpoint" {
+     -re ".*Your system does not support exec catchpoints.*$gdb_prompt $" {
+       unsupported "continue to first exec catchpoint"
+     }
+     -re ".*Catchpoint.*$gdb_prompt $" {
+       set has_exec_catchpoints 1
+       pass "continue to first exec catchpoint"
+     }
+   }
+
+   if {$has_exec_catchpoints == 0} {
+     unsupported "exec catchpoints"
+     return
+   }
+
+   zap_session
+
+   # Start the program running, and stop at main.
+   #
+   if ![runto_main] then {
+     perror "Couldn't run ${testfile}"
+     return
+   }
+
    # Verify that we can see various global and local variables
    # in this program, and that they have expected values.  Some
    # of these variables are also declared in the program we'll
@@ -213,7 +233,7 @@ proc do_exec_tests {} {
    setup_xfail hppa2.0w-hp-hpux* CLLbs16760
    send_gdb "continue\n"
    gdb_expect {
-     -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .START..*$gdb_prompt $"\
+     -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .*$gdb_prompt $"\
                      {pass "hit catch exec"}
      -re "$gdb_prompt $" {fail "hit catch exec"}
      timeout         {fail "(timeout) hit catch exec"}
Index: testsuite/gdb.base/foll-fork.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/foll-fork.exp,v
retrieving revision 1.6
diff -u -p -r1.6 foll-fork.exp
--- testsuite/gdb.base/foll-fork.exp	23 Aug 2007 18:14:16 -0000	1.6
+++ testsuite/gdb.base/foll-fork.exp	19 Oct 2007 17:33:29 -0000
@@ -11,22 +11,16 @@
 # 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/>.  */
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@prep.ai.mit.edu
-
-if $tracelevel then {
-	strace $tracelevel
-	}
-
-if { ![isnative] } then {
+if { [is_remote target] || ![isnative] } then {
     continue
 }
 
 set prms_id 0
 set bug_id 0
 
+global srcfile
 set testfile "foll-fork"
 set srcfile ${testfile}.c
 set binfile ${objdir}/${subdir}/${testfile}
@@ -41,10 +35,32 @@ if  { [gdb_compile "${srcdir}/${subdir}/
 # Until "set follow-fork-mode" and "catch fork" are implemented on
 # other targets...
 #
-if ![istarget "hppa*-hp-hpux*"] then {
+if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
     continue
 }
 
+proc check_fork_catchpoints {} {
+  global gdb_prompt
+
+  # Verify that the system supports "catch fork".
+  gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint"
+  set has_fork_catchpoints 0
+  gdb_test_multiple "continue" "continue to first fork catchpoint" {
+    -re ".*Your system does not support fork catchpoints.*$gdb_prompt $" {
+      unsupported "continue to first fork catchpoint"
+    }
+    -re ".*Catchpoint.*$gdb_prompt $" {
+      set has_fork_catchpoints 1
+      pass "continue to first fork catchpoint"
+    }
+  }
+
+  if {$has_fork_catchpoints == 0} {
+    unsupported "fork catchpoints"
+    return -code return
+  }
+}
+
 proc default_fork_parent_follow {} {
    global gdb_prompt
 
@@ -115,7 +131,7 @@ proc explicit_fork_child_follow {} {
    }
    send_gdb "next 2\n"
    gdb_expect {
-      -re "Detaching from program:.*Attaching after fork to.*$gdb_prompt $"\
+      -re "Attaching after fork to.*$gdb_prompt $"\
                       {pass "explicit child follow, no catchpoints"}
       -re "$gdb_prompt $" {fail "explicit child follow, no catchpoints"}
       timeout         {fail "(timeout) explicit child follow, no catchpoints"}
@@ -129,6 +145,7 @@ proc explicit_fork_child_follow {} {
 
 proc catch_fork_child_follow {} {
    global gdb_prompt
+   global srcfile
 
    send_gdb "catch fork\n"
    gdb_expect {
@@ -153,7 +170,7 @@ proc catch_fork_child_follow {} {
 
    send_gdb "continue\n"
    gdb_expect {
-      -re "Catchpoint.*(forked process.*),.*in _fork_sys.*$gdb_prompt $"\
+      -re "Catchpoint.*(forked process.*),.*in .*fork.*$gdb_prompt $"\
                       {pass "explicit child follow, catch fork"}
       -re "$gdb_prompt $" {fail "explicit child follow, catch fork"}
       timeout         {fail "(timeout) explicit child follow, catch fork"}
@@ -175,7 +192,7 @@ proc catch_fork_child_follow {} {
       -re "$gdb_prompt $" {pass "set follow child"}
       timeout         {fail "(timeout) set follow child"}
    }
-   send_gdb "tbreak 24\n"
+   send_gdb "tbreak ${srcfile}:24\n"
    gdb_expect {
       -re "Breakpoint.*, line 24.*$gdb_prompt $"\
                       {pass "set follow child, tbreak"}
@@ -184,7 +201,7 @@ proc catch_fork_child_follow {} {
    }
    send_gdb "continue\n"
    gdb_expect {
-      -re ".*Detaching from program:.*Attaching after fork to.* at .*24.*$gdb_prompt $"\
+      -re "Attaching after fork to.* at .*24.*$gdb_prompt $"\
                       {pass "set follow child, hit tbreak"}
       -re "$gdb_prompt $" {fail "set follow child, hit tbreak"}
       timeout         {fail "(timeout) set follow child, hit tbreak"}
@@ -211,6 +228,7 @@ proc catch_fork_child_follow {} {
 
 proc tcatch_fork_parent_follow {} {
    global gdb_prompt
+   global srcfile
 
    send_gdb "catch fork\n"
    gdb_expect {
@@ -225,7 +243,7 @@ proc tcatch_fork_parent_follow {} {
 
    send_gdb "continue\n"
    gdb_expect {
-      -re ".*in _fork_sys.*$gdb_prompt $"\
+      -re ".*in .*fork.*$gdb_prompt $"\
                       {pass "explicit parent follow, tcatch fork"}
       -re "$gdb_prompt $" {fail "explicit parent follow, tcatch fork"}
       timeout         {fail "(timeout) explicit parent follow, tcatch fork"}
@@ -235,7 +253,7 @@ proc tcatch_fork_parent_follow {} {
       -re "$gdb_prompt $" {pass "set follow parent"}
       timeout         {fail "(timeout) set follow parent"}
    }
-   send_gdb "tbreak 24\n"
+   send_gdb "tbreak ${srcfile}:24\n"
    gdb_expect {
       -re "Breakpoint.*, line 24.*$gdb_prompt $"\
                       {pass "set follow parent, tbreak"}
@@ -313,6 +331,10 @@ By default, the debugger will follow the
      timeout         {fail "set follow to nonsense is prohibited (reset parent)"}
    }
 
+   # Check that fork catchpoints are supported, as an indicator for whether
+   # fork-following is supported.
+   if [runto_main] then { check_fork_catchpoints }
+
    # Test the default behaviour, which is to follow the parent of a
    # fork, and detach from the child.  Do this without catchpoints.
    #
@@ -357,6 +379,9 @@ gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 
+# The "Detaching..." and "Attaching..." messages may be hidden by
+# default.
+gdb_test "set verbose" ""
 
 # This is a test of gdb's ability to follow the parent, child or both
 # parent and child of a Unix fork() system call.
Index: testsuite/gdb.base/foll-vfork.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/foll-vfork.exp,v
retrieving revision 1.6
diff -u -p -r1.6 foll-vfork.exp
--- testsuite/gdb.base/foll-vfork.exp	23 Aug 2007 18:14:16 -0000	1.6
+++ testsuite/gdb.base/foll-vfork.exp	19 Oct 2007 17:33:29 -0000
@@ -11,16 +11,9 @@
 # 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/>.  */
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@prep.ai.mit.edu
-
-if $tracelevel then {
-	strace $tracelevel
-	}
-
-if { ![isnative] } then {
+if { [is_remote target] || ![isnative] } then {
     continue
 }
 
@@ -35,6 +28,7 @@ set bug_id 0
 ##  return 0
 ##}
 
+global srcfile
 set testfile "foll-vfork"
 set testfile2 "vforked-prog"
 set srcfile ${testfile}.c
@@ -56,7 +50,7 @@ if  { [gdb_compile "${srcdir}/${subdir}/
 # Until "set follow-fork-mode" and "catch vfork" are implemented on
 # other targets...
 #
-if ![istarget "hppa*-hp-hpux*"] then {
+if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
     continue
 }
 
@@ -73,6 +67,29 @@ if [istarget "hppa*-hp-hpux10.20"] then 
 set oldtimeout $timeout
 set timeout [expr "$timeout + 10"]
 
+proc check_vfork_catchpoints {} {
+  global gdb_prompt
+  global has_vfork_catchpoints
+
+  # Verify that the system supports "catch vfork".
+  gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork catchpoint"
+  set has_vfork_catchpoints 0
+  gdb_test_multiple "continue" "continue to first vfork catchpoint" {
+    -re ".*Your system does not support vfork catchpoints.*$gdb_prompt $" {
+      unsupported "continue to first vfork catchpoint"
+    }
+    -re ".*Catchpoint.*$gdb_prompt $" {
+      set has_vfork_catchpoints 1
+      pass "continue to first vfork catchpoint"
+    }
+  }
+
+  if {$has_vfork_catchpoints == 0} {
+    unsupported "vfork catchpoints"
+    return -code return
+  }
+}
+
 proc vfork_parent_follow_through_step {} {
    global gdb_prompt
 
@@ -97,20 +114,21 @@ proc vfork_parent_follow_through_step {}
 
 proc vfork_parent_follow_to_bp {} {
    global gdb_prompt
+   global srcfile
 
    send_gdb "set follow parent\n"
    gdb_expect {
       -re "$gdb_prompt $" {pass "set follow parent, vfork to bp"}
       timeout         {fail "set follow parent, vfork to bp"}
    }
-   send_gdb "break 18\n"
+   send_gdb "break ${srcfile}:18\n"
    gdb_expect {
       -re "$gdb_prompt $" {pass "break, vfork to bp"}
       timeout         {fail "break, vfork to bp"}
    }
    send_gdb "continue\n"
    gdb_expect {
-      -re ".*Detaching after fork from process.*Breakpoint.*18.*$gdb_prompt "\
+      -re ".*Detaching after fork from child process.*Breakpoint.*18.*$gdb_prompt "\
                       {pass "vfork parent follow, to bp"}
       -re "$gdb_prompt $" {fail "vfork parent follow, to bp"}
       timeout         {fail "(timeout) vfork parent follow, to bp" }
@@ -133,7 +151,7 @@ proc vfork_and_exec_child_follow_to_main
    }
    send_gdb "continue\n"
    gdb_expect {
-      -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
+      -re "Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
                       {pass "vfork and exec child follow, to main bp"}
       -re "$gdb_prompt $" {fail "vfork and exec child follow, to main bp"}
       timeout         {fail "(timeout) vfork and exec child follow, to main bp" }
@@ -191,7 +209,7 @@ proc vfork_and_exec_child_follow_through
    }
    send_gdb "next\n"
    gdb_expect {
-      -re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
+      -re "Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt "\
                       {pass "vfork and exec child follow, through step"}
       -re "$gdb_prompt $" {fail "vfork and exec child follow, through step"}
       timeout         {fail "(timeout) vfork and exec child follow, through step" }
@@ -248,7 +266,7 @@ proc tcatch_vfork_then_parent_follow {} 
    gdb_expect {
       -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\
                       {pass "vfork parent follow, tcatch vfork"}
-      -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\
+      -re "vfork \\(\\) at.*$gdb_prompt "\
                       {pass "vfork parent follow, tcatch vfork"}
       -re "$gdb_prompt $" {fail "vfork parent follow, tcatch vfork"}
       timeout         {fail "(timeout) vfork parent follow, tcatch vfork"}
@@ -269,6 +287,7 @@ proc tcatch_vfork_then_parent_follow {} 
 
 proc tcatch_vfork_then_child_follow {} {
    global gdb_prompt
+   global srcfile
    global srcfile2
 
    send_gdb "set follow child\n"
@@ -287,6 +306,8 @@ proc tcatch_vfork_then_child_follow {} {
 # HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
 # stop you in "_vfork".
    gdb_expect {
+      -re "vfork \\(\\) at .*$gdb_prompt $"\
+                      {pass "vfork child follow, tcatch vfork"}
       -re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt "\
                       {pass "vfork child follow, tcatch vfork"}
       -re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt "\
@@ -296,8 +317,10 @@ proc tcatch_vfork_then_child_follow {} {
    }
    send_gdb "finish\n"
    gdb_expect {
-      -re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt "\
+      -re "Run till exit from.*vfork.*${srcfile}:12.*$gdb_prompt "\
                       {pass "vfork child follow, finish after tcatch vfork"}
+      -re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt "\
+                      {pass "vfork child follow, finish after tcatch vfork (followed exec)"}
       -re "$gdb_prompt $" {fail "vfork child follow, finish after tcatch vfork"}
       timeout         {fail "(timeout) vfork child follow, finish after tcatch vfork" }
    }
@@ -311,6 +334,10 @@ proc tcatch_vfork_then_child_follow {} {
 proc do_vfork_and_exec_tests {} {
    global gdb_prompt
 
+   # Check that vfork catchpoints are supported, as an indicator for whether
+   # vfork-following is supported.
+   if [runto_main] then { check_vfork_catchpoints }
+
    # Try following the parent process by stepping through a call to
    # vfork.  Do this without catchpoints.
    if [runto_main] then { vfork_parent_follow_through_step }
@@ -362,6 +389,9 @@ gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 
+# The "Detaching..." and "Attaching..." messages may be hidden by
+# default.
+gdb_test "set verbose" ""
 
 # This is a test of gdb's ability to follow the parent or child
 # of a Unix vfork() system call.  (The child will subsequently


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