From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9589 invoked by alias); 19 Oct 2007 17:59:32 -0000 Received: (qmail 9564 invoked by uid 22791); 19 Oct 2007 17:59:29 -0000 X-Spam-Check-By: sourceware.org Received: from NaN.false.org (HELO nan.false.org) (208.75.86.248) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 19 Oct 2007 17:59:23 +0000 Received: from nan.false.org (localhost [127.0.0.1]) by nan.false.org (Postfix) with ESMTP id E1407982CA for ; Fri, 19 Oct 2007 17:59:21 +0000 (GMT) Received: from caradoc.them.org (22.svnf5.xdsl.nauticom.net [209.195.183.55]) by nan.false.org (Postfix) with ESMTP id 7AA9B980A7 for ; Fri, 19 Oct 2007 17:59:21 +0000 (GMT) Received: from drow by caradoc.them.org with local (Exim 4.68) (envelope-from ) id 1Iiw80-0000EN-Hl for gdb-patches@sourceware.org; Fri, 19 Oct 2007 13:59:20 -0400 Date: Fri, 19 Oct 2007 19:49:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Subject: [RFC] Support exec tracing on GNU/Linux and HP-UX Message-ID: <20071019175920.GA548@caradoc.them.org> Mail-Followup-To: gdb-patches@sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.15 (2007-04-09) X-IsSubscribed: yes 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: 2007-10/txt/msg00456.txt.bz2 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 * 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 * 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 #include @@ -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 . */ +# along with this program. If not, see . -# 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 . */ +# along with this program. If not, see . -# 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 . */ +# along with this program. If not, see . -# 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