From patchwork Tue Jul 4 15:22:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72081 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 94BC5387093F for ; Tue, 4 Jul 2023 15:24:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 94BC5387093F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484263; bh=2WjmivqQFrTiWFzf6SmnjSDzKaIGOZLbSA54cckrpu8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=XNCCg/+4qjlXHuFdevdLO2De60YsT56+ybZgD8szfln28mJDxWww3O7NwEqgOckMQ dmg3i8hDuphgA7IG2GpOJbpDCX54PdfoMQiQVTRIs3dknttlGSsBil1TUUyYxD8Vrk cEDDFOaLo1/AxWURD6g975xzB7tWpM+lQFR18t04= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 70051385558C for ; Tue, 4 Jul 2023 15:23:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 70051385558C Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-552-bpw0VZGYPq61eoNw36KySg-1; Tue, 04 Jul 2023 11:23:13 -0400 X-MC-Unique: bpw0VZGYPq61eoNw36KySg-1 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3142665f122so2457206f8f.0 for ; Tue, 04 Jul 2023 08:23:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484192; x=1691076192; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2WjmivqQFrTiWFzf6SmnjSDzKaIGOZLbSA54cckrpu8=; b=cOGe0k4T9lW6b9XxcecWS538+wpXZLk+BEtQungdqDBosXKnXPFaPT3ot2v/nxcp5q ykDxqCnH4NiIyVvcHE2/R7k0reZh1HxK27JU9XRGkSpni6jZd5Csd46h8lU3bh208w17 +rd97HBMI2/pZvkMLvOb2v/sfn/TBvDK+EYIsHy2bpZiqW0vqWcEknhtdyFb1NZcjoHo ZWY9Y3n/pMufBXRqE43unbxvFRQYO50j6ZKRVM0OFy+drp08uiysVodKkC239O3+b89G DCzgvrN2wkNoiFeQkssuzmZffhGZbmDfUUKy+a8Arrdfrz0a92G4LhGr+htotObP1p1m sV+g== X-Gm-Message-State: ABy/qLbfpNEuv8K+nm5+ZSVo47PeYdbf0fF69kny4XNbp7124fPqUskY z0x1FLF1EsQ4wZGTHH8Wo/DoKiA+HXkRJh9SWWkKZ1qzWIXedi6kBhqw3DBbaP0knutCrkgv+Md JOnQZ1Y68Tzp5NUdorRjzpjT1zZvQ7nb9mWubnxB3B0HV4niH6F4O8D2YKBUqVSvocg4xwQrtfm jI9Ttavg== X-Received: by 2002:a5d:5511:0:b0:313:f59c:95ec with SMTP id b17-20020a5d5511000000b00313f59c95ecmr10770691wrv.28.1688484191586; Tue, 04 Jul 2023 08:23:11 -0700 (PDT) X-Google-Smtp-Source: APBJJlGb+Mpgt1rvk10m1WXPJm6mCTP1X5d5t88g54Lf4PL6YhNDkh8dB9apeXfWeuSkRqXKvL4HEg== X-Received: by 2002:a5d:5511:0:b0:313:f59c:95ec with SMTP id b17-20020a5d5511000000b00313f59c95ecmr10770662wrv.28.1688484191006; Tue, 04 Jul 2023 08:23:11 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id fa12-20020a05600c518c00b003fbb1ce274fsm16121545wmb.0.2023.07.04.08.23.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:10 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 6/8] gdb/testsuite: expand gdb.base/foll-vfork.exp Date: Tue, 4 Jul 2023 16:22:56 +0100 Message-Id: <20cb4bbc67707268a75d32b8eaa539758ac4b31b.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This commit provides tests for all of the bugs fixed in the previous four commits, this is achieved by expanding gdb.base/foll-vfork.exp to run with different configurations: * target-non-stop on/off * non-stop on/off * schedule-multiple on/off We don't test with schedule-multiple on if we are using a remote target, this is due to bug gdb/30574. I've added a link to that bug in this commit, but all this commit does is expose that bug, there's no fixes here. Some of the bugs fixed in the previous commits are very timing dependent, as such, they don't always show up. I've had more success when running this test on a very loaded machine -- I usually run ~8 copies of the test in parallel, then the bugs would normally show up pretty quickly. Other than running the test in more configurations, I've not made any changes to what is actually being tested, other than in one place where, when testing with non-stop mode, GDB stops in a different inferior, as such I had to add a new 'inferior 2' call, this can be found in vfork_relations_in_info_inferiors. I have cleaned things up a little, for example, making use of proc_with_prefix to remove some with_test_prefix calls. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30574 --- gdb/testsuite/gdb.base/foll-vfork.exp | 628 ++++++++++++-------------- 1 file changed, 300 insertions(+), 328 deletions(-) diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index bdceff0f5de..be0715b05c0 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -25,56 +25,52 @@ if {![istarget "*-linux*"]} { continue } -standard_testfile +standard_testfile .c -exit.c vforked-prog.c -set compile_options debug +set binfile $testfile +set binfile2 ${testfile}-exit +set binfile3 vforked-prog -if {[build_executable $testfile.exp $testfile $srcfile $compile_options] == -1} { +if {[build_executable "compile $binfile" $binfile $srcfile] == -1} { untested "failed to compile main testcase" return -1 } -set testfile2 "vforked-prog" -set srcfile2 ${testfile2}.c +if {[build_executable "compile $binfile2" $binfile2 $srcfile2] == -1} { + untested "failed to compile main testcase" + return -1 +} -if {[build_executable $testfile.exp $testfile2 $srcfile2 $compile_options] == -1} { - untested "failed to compile secondary testcase" +if {[build_executable "compile $binfile3" $binfile3 $srcfile3] == -1} { + untested "failed to compile main testcase" return -1 } +# If required, download the program that we exec after vfork to the +# remote target. if { [is_remote target] } { - gdb_remote_download target [standard_output_file $testfile2] + gdb_remote_download target [standard_output_file $binfile3] } -# A few of these tests require a little more time than the standard -# timeout allows. -set oldtimeout $timeout -set timeout [expr "$timeout + 10"] - # Start with a fresh GDB, with verbosity enabled, and run to main. On # error, behave as "return", so we don't try to continue testing with # a borked session. -proc setup_gdb {} { - global testfile srcfile - - clean_restart $testfile +proc setup_gdb { binfile srcfile } { + clean_restart $binfile if ![runto_main] { return -code return } - set tbreak_line [gdb_get_line_number " VFORK " $srcfile] - gdb_test "tbreak ${tbreak_line}" - gdb_continue_to_breakpoint ".*" + gdb_breakpoint [gdb_get_line_number " VFORK " $srcfile] temporary + gdb_continue_to_breakpoint "at VFORK" } proc check_vfork_catchpoints {} { - global gdb_prompt - # Because setup_gdb uses 'return -code return' which would return to # our caller we need to wrap this call, spot when setup_gdb failed # (with return code 2), and then issue our own 'return -code return'. - set code [catch {setup_gdb} string] + set code [catch {setup_gdb $::testfile $::srcfile} string] if { $code == 2 } { unsupported "vfork catchpoints" return -code return @@ -84,10 +80,10 @@ proc check_vfork_catchpoints {} { 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 this type\r\nof catchpoint.*$gdb_prompt $" { + -re -wrap ".*Your system does not support this type\r\nof catchpoint.*" { unsupported "continue to first vfork catchpoint" } - -re ".*Catchpoint.*$gdb_prompt $" { + -re -wrap ".*Catchpoint.*" { set has_vfork_catchpoints 1 pass "continue to first vfork catchpoint" } @@ -99,319 +95,278 @@ proc check_vfork_catchpoints {} { } } -proc vfork_parent_follow_through_step {} { - with_test_prefix "vfork parent follow, through step" { - global gdb_prompt +proc_with_prefix vfork_parent_follow_through_step { binfile srcfile } { + setup_gdb $binfile $srcfile - setup_gdb + gdb_test_no_output "set follow-fork parent" - gdb_test_no_output "set follow-fork parent" + gdb_test_multiple "next" "" { + -re -wrap "\\\[Detaching after vfork from.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } - set test "step" - gdb_test_multiple "next" $test { - -re "\\\[Detaching after vfork from.*if \\(pid == 0\\).*$gdb_prompt " { - pass $test - } - } - # The child 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_parent_follow_to_bp {} { - with_test_prefix "vfork parent follow, to bp" { - global gdb_prompt - global srcfile - - setup_gdb - - gdb_test_no_output "set follow-fork parent" - - set bp_location [gdb_get_line_number "I'm the proud parent of child"] - gdb_test "break ${srcfile}:${bp_location}" ".*" "break, vfork to bp" - - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re ".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*$gdb_prompt " { - pass $test - } - } - # The child 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 -}} - -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 " { - # PR 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 -}} + # The child 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 - global srcfile2 +proc_with_prefix vfork_parent_follow_to_bp { binfile srcfile } { + setup_gdb $binfile $srcfile - setup_gdb + gdb_test_no_output "set follow-fork parent" - gdb_test_no_output "set follow-fork child" + set bp_location \ + [gdb_get_line_number "I'm the proud parent of child" $srcfile] + gdb_test "break ${srcfile}:${bp_location}" ".*" "break, vfork to bp" - set linenum [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] + gdb_test_multiple "continue" "continue to bp" { + -re -wrap ".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*" { + pass $gdb_test_name + } + } - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$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_through_step {} { - with_test_prefix "vfork and exec child follow, through step" { - global gdb_prompt - global srcfile2 - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - set test "step over vfork" - - # The ideal support is to be able to debug the child even - # before it execs. Thus, "next" lands on the next line after - # the vfork. - gdb_test_multiple "next" $test { - -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$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 expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} + # The child 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 +} + +proc_with_prefix vfork_child_follow_to_exit { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test_multiple "continue" "continue to child exit" { + -re -wrap "Couldn't get registers.*" { + # PR gdb/14766 + fail $gdb_test_name + } + -re -wrap "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent .* after child exit.*" { + pass $gdb_test_name + } + } + + # 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_with_prefix vfork_and_exec_child_follow_to_main_bp { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + set linenum [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + + gdb_test_multiple "continue" "continue to bp" { + -re -wrap "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*" { + pass $gdb_test_name + } + } + + # 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_with_prefix vfork_and_exec_child_follow_through_step { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + # The ideal support is to be able to debug the child even + # before it execs. Thus, "next" lands on the next line after + # the vfork. + gdb_test_multiple "next" "next over vfork" { + -re -wrap "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } + + # 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 +} proc continue_to_vfork {} { - global gdb_prompt - - # A vfork catchpoint may stop in either "vfork" or "_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 - } - } + # A vfork catchpoint may stop in either "vfork" or "_vfork". + gdb_test_multiple "continue" "continue to vfork" { + -re -wrap "vfork \\(\\) at .*" { + pass $gdb_test_name + } + -re -wrap "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*" { + pass $gdb_test_name + } + } } -proc tcatch_vfork_then_parent_follow {} { - with_test_prefix "vfork parent follow, finish after tcatch vfork" { - global gdb_prompt - global srcfile - - setup_gdb - - gdb_test_no_output "set follow-fork parent" - - gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - - continue_to_vfork - - set linenum [gdb_get_line_number "pid = vfork ();"] - set test "finish" - gdb_test_multiple "finish" $test { - -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:${linenum}.*$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 child 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 -}} - -proc tcatch_vfork_then_child_follow_exec {} { - with_test_prefix "vfork child follow, finish after tcatch vfork" { - global gdb_prompt - global srcfile - global srcfile2 - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - - continue_to_vfork - - set linenum1 [gdb_get_line_number "pid = vfork ();"] - set linenum2 [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] - - set test "finish" - gdb_test_multiple "finish" $test { - -re "Run till exit from.*vfork.*${srcfile}:${linenum1}.*$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 - } - -re "Run till exit from.*vfork.*${srcfile2}:${linenum2}.*$gdb_prompt " { - pass "$test (followed exec)" - } - } - # 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 -}} - -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).*" - - continue_to_vfork - - set test "finish" - gdb_test_multiple "finish" $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 -}} +proc_with_prefix tcatch_vfork_then_parent_follow { binfile srcfile } { + setup_gdb $binfile $srcfile -proc vfork_relations_in_info_inferiors { variant } { - with_test_prefix "vfork relations in info inferiors" { - global gdb_prompt + gdb_test_no_output "set follow-fork parent" - setup_gdb + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - gdb_test_no_output "set follow-fork child" + continue_to_vfork - set test "step over vfork" - gdb_test_multiple "next" $test { - -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " { - pass "$test" - } - } + set linenum [gdb_get_line_number "pid = vfork ();" $srcfile] + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:${linenum}.*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + send_gdb "finish\n" + exp_continue + } + } - gdb_test "info inferiors" \ - ".*is vfork parent of inferior 2.*is vfork child of inferior 1" \ - "info inferiors shows vfork parent/child relation" + # The child 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 +} - if { $variant == "exec" } { - global srcfile2 +proc_with_prefix tcatch_vfork_then_child_follow_exec { binfile srcfile } { + setup_gdb $binfile $srcfile - set linenum [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re ".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " { - pass $test - } - } - } else { - set test "continue to child exit" - gdb_test_multiple "continue" $test { - -re "exited normally.*$gdb_prompt " { - pass $test + gdb_test_no_output "set follow-fork child" + + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" + + continue_to_vfork + + set linenum1 [gdb_get_line_number "pid = vfork ();" $srcfile] + set linenum2 [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*${srcfile}:${linenum1}.*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + send_gdb "finish\n" + exp_continue + } + -re -wrap "Run till exit from.*vfork.*${::srcfile3}:${linenum2}.*" { + pass "$gdb_test_name (followed exec)" + } + } + + # 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 +} + +proc tcatch_vfork_then_child_follow_exit { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" + + continue_to_vfork + + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*exited normally.*" { + setup_kfail "gdb/14762" *-*-* + fail $gdb_test_name + } + -re -wrap "Run till exit from.*vfork.*pid = vfork \\(\\).*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + 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 +} + +proc_with_prefix vfork_relations_in_info_inferiors { variant binfile srcfile non_stop } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test_multiple "next" "next over vfork" { + -re -wrap "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } + + if { $non_stop } { + gdb_test "inferior 2" ".*" + } + + gdb_test "info inferiors" \ + ".*is vfork parent of inferior 2.*is vfork child of inferior 1" \ + "info inferiors shows vfork parent/child relation" + + if { $variant == "exec" } { + set linenum [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + gdb_test_multiple "continue" "continue to bp" { + -re -wrap ".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*" { + pass $gdb_test_name + } + } + } else { + gdb_test_multiple "continue" "continue to child exit" { + -re -wrap "exited normally.*" { + pass $gdb_test_name } - } - } - - set test "vfork relation no longer appears in info inferiors" - gdb_test_multiple "info inferiors" $test { - -re -wrap "is vfork child of inferior 1.*" { - fail $test - } - -re -wrap "is vfork parent of inferior 2.*" { - fail $test - } - -re -wrap "" { - pass $test - } - } -}} - -proc do_vfork_and_follow_parent_tests {} { - global gdb_prompt + } + } + gdb_test_multiple "info inferiors" "vfork relation no longer appears in info inferiors" { + -re -wrap "is vfork child of inferior 1.*" { + fail $gdb_test_name + } + -re -wrap "is vfork parent of inferior 2.*" { + fail $gdb_test_name + } + -re -wrap "" { + pass $gdb_test_name + } + } +} + +proc do_vfork_and_follow_parent_tests { binfile srcfile } { # Try following the parent process by stepping through a call to # vfork. Do this without catchpoints. - vfork_parent_follow_through_step + vfork_parent_follow_through_step $binfile $srcfile # Try following the parent process by setting a breakpoint on the # other side of a vfork, and running to that point. Do this # without catchpoints. - vfork_parent_follow_to_bp + vfork_parent_follow_to_bp $binfile $srcfile # Try catching a vfork, and stepping out to the parent. # - tcatch_vfork_then_parent_follow + tcatch_vfork_then_parent_follow $binfile $srcfile } -proc do_vfork_and_follow_child_tests_exec {} { +proc do_vfork_and_follow_child_tests_exec { binfile srcfile non_stop } { # 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. # - vfork_and_exec_child_follow_to_main_bp + vfork_and_exec_child_follow_to_main_bp $binfile $srcfile # Try following the child process by stepping through a call to # vfork. The child also executes an exec. Since the child cannot @@ -420,11 +375,11 @@ proc do_vfork_and_follow_child_tests_exec {} { # recomputed in the exec'd child, the step through a vfork should # land us in the "main" for the exec'd child, too. # - vfork_and_exec_child_follow_through_step + vfork_and_exec_child_follow_through_step $binfile $srcfile # Try catching a vfork, and stepping out to the child. # - tcatch_vfork_then_child_follow_exec + tcatch_vfork_then_child_follow_exec $binfile $srcfile # Test the ability to follow both child and parent of a vfork. Do # this without catchpoints. @@ -442,25 +397,25 @@ proc do_vfork_and_follow_child_tests_exec {} { # and confirm the relation is no longer displayed in "info # inferiors". # - vfork_relations_in_info_inferiors "exec" + vfork_relations_in_info_inferiors "exec" $binfile $srcfile $non_stop } -proc do_vfork_and_follow_child_tests_exit {} { +proc do_vfork_and_follow_child_tests_exit { binfile srcfile non_stop } { # Try following the child process by just continuing through the # vfork, and letting the child exit. # - vfork_child_follow_to_exit + vfork_child_follow_to_exit $binfile $srcfile # Try catching a vfork, and stepping out to the child. # - tcatch_vfork_then_child_follow_exit + tcatch_vfork_then_child_follow_exit $binfile $srcfile # Step over a vfork in the child, do "info inferiors" and check the # parent/child relation is displayed. Run the child to completion, # and confirm the relation is no longer displayed in "info # inferiors". # - vfork_relations_in_info_inferiors "exit" + vfork_relations_in_info_inferiors "exit" $binfile $srcfile $non_stop } with_test_prefix "check vfork support" { @@ -470,41 +425,58 @@ with_test_prefix "check vfork support" { } # Follow parent and follow child vfork tests with a child that execs. -with_test_prefix "exec" { +proc_with_prefix exec_tests { binfile srcfile non_stop } { # 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 + do_vfork_and_follow_parent_tests $binfile $srcfile # 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 + do_vfork_and_follow_child_tests_exec $binfile $srcfile $non_stop } # Follow parent and follow child vfork tests with a child that exits. -with_test_prefix "exit" { +proc_with_prefix exit_tests { binfile srcfile non_stop } { # 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 + do_vfork_and_follow_parent_tests $binfile $srcfile # 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 + do_vfork_and_follow_child_tests_exit $binfile $srcfile $non_stop +} + +# Using the remote protocol with schedule-multiple turned triggers bug +# gdb/30574, so avoid this for now. +if {[target_info exists gdb_protocol] + && ([target_info gdb_protocol] == "remote" + || [target_info gdb_protocol] == "extended-remote")} { + set sm_modes { off } +} else { + set sm_modes { off on } } -set timeout $oldtimeout +# A few of these tests require a little more time than the standard timeout +# allows. +with_timeout_factor 2 { + foreach_with_prefix target-non-stop {auto on off} { + foreach_with_prefix non-stop {off on} { + foreach_with_prefix schedule-multiple $sm_modes { + save_vars { ::GDBFLAGS } { + # These flags will be picked up by the call to + # clean_restart inside setup_gdb. + append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" + append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" + append ::GDBFLAGS " -ex \"set schedule-multiple ${schedule-multiple}\"" + + exec_tests $binfile $srcfile ${non-stop} + exit_tests $binfile2 $srcfile2 ${non-stop} + } + } + } + } +}