From patchwork Mon Nov 28 18:40:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61181 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 BA7473853D4E for ; Mon, 28 Nov 2022 18:41:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BA7473853D4E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660886; bh=d7KIMio0lDGzHegbUc7OL3/DFDZe/ct0DsnV/24NGnk=; 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=aQpYJi6jqZwUoXVQioykCgTi9QGS8jGnfwQVnK/JYwPljzPecNfVK7L87J01dZJXu DU86TbjETcke0G5diRhag1g4cNxLESXH1yYYR+Ojsu5Jhig9k8hz0NsBKHH8FibryC YXXUiQsA3iAFEUVpLKPCw/bByH8TJbWVoVNEvGnE= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 1F3E2385841D for ; Mon, 28 Nov 2022 18:40:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1F3E2385841D X-ASG-Debug-ID: 1669660845-0c856e02a143f580001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id xJmL904Xz5E9saql (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:45 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 20923441D65; Mon, 28 Nov 2022 13:40:45 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Tiezhu Yang Subject: [PATCH gdb-12-branch 1/6] gdb: testsuite: add new gdb_attach to check "attach" command Date: Mon, 28 Nov 2022 13:40:37 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 1/6] gdb: testsuite: add new gdb_attach to check "attach" command Message-Id: <20221128184042.3781569-2-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660845 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 1418 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Tiezhu Yang This commit adds new gdb_attach to centralize the failure checking of "attach" command. Return 0 if attach failed, otherwise return 1. Signed-off-by: Tiezhu Yang Change-Id: I553cf386cef60c67d38e331904b4aa01e132104a --- gdb/testsuite/lib/gdb.exp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 6f6acfe188a..819dfbfafca 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -5151,6 +5151,32 @@ gdb_caching_proc can_spawn_for_attach { return 1 } +# Centralize the failure checking of "attach" command. +# Return 0 if attach failed, otherwise return 1. + +proc gdb_attach { testpid args } { + parse_args { + {pattern ""} + } + + if { [llength $args] != 0 } { + error "Unexpected arguments: $args" + } + + gdb_test_multiple "attach $testpid" "attach" { + -re -wrap "Attaching to.*ptrace: Operation not permitted\\." { + unsupported "$gdb_test_name (Operation not permitted)" + return 0 + } + -re -wrap "$pattern" { + pass $gdb_test_name + return 1 + } + } + + return 0 +} + # Kill a progress previously started with spawn_wait_for_attach, and # reap its wait status. PROC_SPAWN_ID is the spawn id associated with # the process. From patchwork Mon Nov 28 18:40:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61183 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 74E6338532C7 for ; Mon, 28 Nov 2022 18:41:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 74E6338532C7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660890; bh=ex7MB+d5oo1LC5HSePuOKWcZ0s4z8+5Eumj8Iy58DAw=; 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=ZGN3v6Cq0sVvol51F7L+fYFTP3A7XvbRKQBoDFlpKr7OHQ0tRiJz2o42DWgnij3vJ XML6yB0peL1PzR5Ib+EK1ANSKc7P0g0wKaDnkNuAgy4pnWyAiImsGImJkqfR8608Fn 9gJh+75KHTunCxxnTAFMZTl9UKFeniOCcgWofpJc= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 1F6FA3857C51 for ; Mon, 28 Nov 2022 18:40:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1F6FA3857C51 X-ASG-Debug-ID: 1669660845-0c856e02a043f3a0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id AHGRCDNTfAv3E6B6 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:45 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id A19AE441B21; Mon, 28 Nov 2022 13:40:45 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH gdb-12-branch 2/6] gdb/testsuite: remove global declarations in gdb.threads/detach-step-over.exp Date: Mon, 28 Nov 2022 13:40:38 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 2/6] gdb/testsuite: remove global declarations in gdb.threads/detach-step-over.exp Message-Id: <20221128184042.3781569-3-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660845 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 4886 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Before doing further changes to this file, change to use the :: notation instead of declaring global variables with the `global` keyword. Change-Id: I72301fd8f4693fea61aac054ba17245a1f4442fb Approved-By: Andrew Burgess --- .../gdb.threads/detach-step-over.exp | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp index 15af7e0e723..917be2ef378 100644 --- a/gdb/testsuite/gdb.threads/detach-step-over.exp +++ b/gdb/testsuite/gdb.threads/detach-step-over.exp @@ -58,24 +58,18 @@ set bp_lineno [gdb_get_line_number "Set breakpoint here"] # The test proper. See description above. proc test {condition_eval target_non_stop non_stop displaced} { - global binfile srcfile - global gdb_prompt - global decimal - global bp_lineno - global GDBFLAGS - # Number of threads started by the program. set n_threads 10 - save_vars { GDBFLAGS } { - append GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\"" - append GDBFLAGS " -ex \"set non-stop $non_stop\"" - append GDBFLAGS " -ex \"set displaced $displaced\"" - append GDBFLAGS " -ex \"set schedule-multiple on\"" - clean_restart $binfile + save_vars { ::GDBFLAGS } { + append ::GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\"" + append ::GDBFLAGS " -ex \"set non-stop $non_stop\"" + append ::GDBFLAGS " -ex \"set displaced $displaced\"" + append ::GDBFLAGS " -ex \"set schedule-multiple on\"" + clean_restart $::binfile } - set test_spawn_id [spawn_wait_for_attach $binfile] + set test_spawn_id [spawn_wait_for_attach $::binfile] set testpid [spawn_id_get_pid $test_spawn_id] set any "\[^\r\n\]*" @@ -83,7 +77,7 @@ proc test {condition_eval target_non_stop non_stop displaced} { gdb_test "add-inferior" "Added inferior 2.*" gdb_test "inferior 2" "Switching to .*" - gdb_load $binfile + gdb_load $::binfile if ![runto setup_done] then { fail "can't run to setup_done" kill_wait_spawned_process $test_spawn_id @@ -95,7 +89,7 @@ proc test {condition_eval target_non_stop non_stop displaced} { # Get the PID of the test process. set pid_inf2 "" gdb_test_multiple "p mypid" "get pid of inferior 2" { - -re " = ($decimal)\r\n$gdb_prompt $" { + -re " = ($::decimal)\r\n$::gdb_prompt $" { set pid_inf2 $expect_out(1,string) pass $gdb_test_name } @@ -124,13 +118,13 @@ proc test {condition_eval target_non_stop non_stop displaced} { # Prevent -readnow timeout. exp_continue } - -re "is a zombie - the process has already terminated.*$gdb_prompt " { + -re "is a zombie - the process has already terminated.*$::gdb_prompt " { fail $gdb_test_name } - -re "Unable to attach: .*$gdb_prompt " { + -re "Unable to attach: .*$::gdb_prompt " { fail $gdb_test_name } - -re "\r\n$gdb_prompt " { + -re "\r\n$::gdb_prompt " { if { $saw_attaching } { set attached 1 pass $test @@ -173,7 +167,7 @@ proc test {condition_eval target_non_stop non_stop displaced} { } # Set threads stepping over a breakpoint continuously. - gdb_test "break $srcfile:$bp_lineno if 0" "Breakpoint.*" \ + gdb_test "break $::srcfile:$::bp_lineno if 0" "Breakpoint.*" \ "break LOC if 0" if {$attempt < $attempts} { @@ -192,7 +186,7 @@ proc test {condition_eval target_non_stop non_stop displaced} { set cont_cmd_re [string_to_regexp $cont_cmd] gdb_test_multiple $cont_cmd "" { - -re "^$cont_cmd_re\r\nContinuing\.\r\n$gdb_prompt " { + -re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " { pass $gdb_test_name } } @@ -208,14 +202,14 @@ proc test {condition_eval target_non_stop non_stop displaced} { incr running_count exp_continue } - -re "Cannot execute this command while the target is running.*$gdb_prompt $" { + -re "Cannot execute this command while the target is running.*$::gdb_prompt $" { # Testing against a remote server that doesn't do # non-stop mode. Explicitly interrupt. This # doesn't test the same code paths in GDB, but # it's still something. set interrupted 1 gdb_test_multiple "interrupt" "" { - -re "$gdb_prompt " { + -re "$::gdb_prompt " { gdb_test_multiple "" $gdb_test_name { -re "received signal SIGINT, Interrupt" { pass $gdb_test_name @@ -224,7 +218,7 @@ proc test {condition_eval target_non_stop non_stop displaced} { } } } - -re "$gdb_prompt $" { + -re "$::gdb_prompt $" { gdb_assert {$running_count == ($n_threads + 1) * 2} $gdb_test_name } } From patchwork Mon Nov 28 18:40:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61187 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 3A5023851894 for ; Mon, 28 Nov 2022 18:42:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3A5023851894 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660975; bh=XBBJ7A3CJe0do57z84BR15JzgOwZFyrgdkWGbbPZWzw=; 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=EH2EDvNDseffz1O0ogas5o25Fmm43YvyIA9FruAAoAyBa4A4cb6oyctUc3MDNY4SX /FTUc+0jiPV+IHjX24gBSvuSJ8AodrThx2lQvzmU0roXNNimb7Q/66nmhQDF/VdR1F pBD47S/e46sNYqqilH2kvMgO21/bGzCYvr8RjjmA= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 20485385B19A for ; Mon, 28 Nov 2022 18:40:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 20485385B19A X-ASG-Debug-ID: 1669660846-0c856e02a143f590001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id l3JzyCmaUsivm17S (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:46 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 2BE3F441B21; Mon, 28 Nov 2022 13:40:46 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Andrew Burgess , Simon Marchi Subject: [PATCH gdb-12-branch 3/6] gdb/testsuite: refactor gdb.threads/detach-step-over.exp Date: Mon, 28 Nov 2022 13:40:39 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 3/6] gdb/testsuite: refactor gdb.threads/detach-step-over.exp Message-Id: <20221128184042.3781569-4-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660846 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 9660 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Andrew Burgess Factor out some bits of gdb.threads/detach-step-over.exp to procs in preparation to adding some new variations of the test. Rename the existing "test" proc and make it use proc_with_prefix. Co-Authored-By: Simon Marchi Change-Id: Ib4412545c81c8556029e0f7bfa9dd48d7a9f3189 --- .../gdb.threads/detach-step-over.exp | 238 ++++++++++-------- 1 file changed, 138 insertions(+), 100 deletions(-) diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp index 917be2ef378..ad9b08f549e 100644 --- a/gdb/testsuite/gdb.threads/detach-step-over.exp +++ b/gdb/testsuite/gdb.threads/detach-step-over.exp @@ -56,11 +56,11 @@ standard_testfile set bp_lineno [gdb_get_line_number "Set breakpoint here"] -# The test proper. See description above. -proc test {condition_eval target_non_stop non_stop displaced} { - # Number of threads started by the program. - set n_threads 10 +# Number of threads started by the program. +set n_threads 10 +# Start GDB, configuring various settings according to the arguments. +proc start_gdb_for_test {condition_eval target_non_stop non_stop displaced} { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\"" append ::GDBFLAGS " -ex \"set non-stop $non_stop\"" @@ -69,10 +69,137 @@ proc test {condition_eval target_non_stop non_stop displaced} { clean_restart $::binfile } + gdb_test_no_output "set breakpoint condition-evaluation $condition_eval" +} + +# Use the 'attach' command to attach to process with pid TESTPID. Return true +# if we believe GDB has attached and we are back at the GDB prompt, otherwise, +# return false. +proc attach_to {testpid} { + with_timeout_factor 2 { + set attached 0 + set saw_attaching 0 + gdb_test_multiple "attach $testpid" "attach" { + -re "Attaching to program.*process $testpid\r\n" { + set saw_attaching 1 + exp_continue + } + -re "new threads in iteration" { + # Seen when "set debug libthread_db" is on. + exp_continue + } + -re "Reading symbols from|Expanding full symbols from" { + # Prevent -readnow timeout. + exp_continue + } + -re "is a zombie - the process has already terminated.*$::gdb_prompt " { + fail $gdb_test_name + } + -re "Unable to attach: .*$::gdb_prompt " { + fail $gdb_test_name + } + -re "\r\n$::gdb_prompt " { + if { $saw_attaching } { + set attached 1 + pass $gdb_test_name + } else { + fail $gdb_test_name + } + } + } + } + + return $attached +} + +# After attaching to a multi-threaded inferior in non-stop mode, we expect to +# see a stop message from each thread. This proc waits for all of these stop +# messages. TID_RE is a regexp used to match the thread-id of the stopped +# thread. +# +# Return true if we saw a stop from each of the expected threads (based on the +# global N_THREADS value), otherwise, return false. +proc check_stops_after_non_stop_attach {tid_re} { + set any "\[^\r\n\]*" + + # In non-stop, we will see one stop per thread after the prompt. + set stops 0 + set test "seen all stops" + for {set thread 1} { $thread <= $::n_threads } { incr thread } { + if {[gdb_test_multiple "" $test { + -re "Thread ${tid_re} ${any} stopped" { + incr stops + } + }] != 0} { + break + } + } + + # If we haven't seen all stops, then the + # gdb_test_multiple in the loop above will have + # already issued a FAIL. + if {$stops != $::n_threads} { + return false + } + pass $test + return true +} + +# Prepare for a single test iteration. TESTPID is the pid of the process GDB +# will be attached too. NON_STOP indicates if GDB is configured in non-stop +# mode or not. ATTEMPT is the current attempt number, and ATTEMPTS is the +# maximum number of attempts we plan to run. TID_RE is a string used to match +# against a thread-id in GDB's stop messages. +# +# Return true if everything is prepared correctly, otherwise return false. +proc prepare_test_iter {testpid non_stop attempt attempts tid_re} { + if {![attach_to $testpid]} { + return false + } + + if {$non_stop} { + if {![check_stops_after_non_stop_attach $tid_re]} { + return false + } + } + + gdb_test "break ${::srcfile}:${::bp_lineno} if 0" "Breakpoint.*" \ + "break LOC if 0" + + if {$attempt < $attempts} { + # Kick the time out timer for another round. + gdb_test "print again = 1" " = 1" "reset timer in the inferior" + # Show the time we had left in the logs, in case + # something goes wrong. + gdb_test "print seconds_left" " = .*" + } + + if {$non_stop} { + set cont_cmd "continue -a &" + } else { + set cont_cmd "continue &" + } + + set cont_cmd_re [string_to_regexp $cont_cmd] + gdb_test_multiple $cont_cmd "" { + -re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " { + pass $gdb_test_name + } + } + + # Wait a bit, to give time for the threads to hit the + # breakpoint. + sleep 1 + + return true +} + +# The test proper. See the description at the top of the file. +proc_with_prefix test_detach_command {condition_eval target_non_stop non_stop displaced} { set test_spawn_id [spawn_wait_for_attach $::binfile] set testpid [spawn_id_get_pid $test_spawn_id] - set any "\[^\r\n\]*" + start_gdb_for_test $condition_eval $target_non_stop $non_stop $displaced gdb_test "add-inferior" "Added inferior 2.*" gdb_test "inferior 2" "Switching to .*" @@ -84,8 +211,6 @@ proc test {condition_eval target_non_stop non_stop displaced} { return } - gdb_test_no_output "set breakpoint condition-evaluation $condition_eval" - # Get the PID of the test process. set pid_inf2 "" gdb_test_multiple "p mypid" "get pid of inferior 2" { @@ -100,101 +225,12 @@ proc test {condition_eval target_non_stop non_stop displaced} { with_test_prefix "iter $attempt" { gdb_test "inferior 1" "Switching to .*" - with_timeout_factor 2 { - set attached 0 - set saw_attaching 0 - set eperm 0 - set test "attach" - gdb_test_multiple "attach $testpid" $test { - -re "Attaching to program.*process $testpid\r\n" { - set saw_attaching 1 - exp_continue - } - -re "new threads in iteration" { - # Seen when "set debug libthread_db" is on. - exp_continue - } - -re "Reading symbols from|Expanding full symbols from" { - # Prevent -readnow timeout. - exp_continue - } - -re "is a zombie - the process has already terminated.*$::gdb_prompt " { - fail $gdb_test_name - } - -re "Unable to attach: .*$::gdb_prompt " { - fail $gdb_test_name - } - -re "\r\n$::gdb_prompt " { - if { $saw_attaching } { - set attached 1 - pass $test - } else { - fail $test - } - } - } - } - - if {!$attached} { + if {![prepare_test_iter $testpid $non_stop \ + $attempt $attempts "$::decimal\.$::decimal"]} { kill_wait_spawned_process $test_spawn_id return } - if {$non_stop} { - # In non-stop, we will see one stop per thread after - # the prompt. - set stops 0 - set tid_re "$::decimal\.$::decimal" - set test "seen all stops" - for {set thread 1} { $thread <= $n_threads } { incr thread } { - if {[gdb_test_multiple "" $test { - -re "Thread ${tid_re} ${any} stopped" { - incr stops - } - }] != 0} { - break - } - } - - # If we haven't seen all stops, then the - # gdb_test_multiple in the loop above will have - # already issued a FAIL. - if {$stops != $n_threads} { - kill_wait_spawned_process $test_spawn_id - return - } - pass $test - } - - # Set threads stepping over a breakpoint continuously. - gdb_test "break $::srcfile:$::bp_lineno if 0" "Breakpoint.*" \ - "break LOC if 0" - - if {$attempt < $attempts} { - # Kick the time out timer for another round. - gdb_test "print again = 1" " = 1" "reset timer in the inferior" - # Show the time we had left in the logs, in case - # something goes wrong. - gdb_test "print seconds_left" " = .*" - } - - if {$non_stop} { - set cont_cmd "continue -a &" - } else { - set cont_cmd "continue &" - } - - set cont_cmd_re [string_to_regexp $cont_cmd] - gdb_test_multiple $cont_cmd "" { - -re "^$cont_cmd_re\r\nContinuing\.\r\n$::gdb_prompt " { - pass $gdb_test_name - } - } - - # Wait a bit, to give time for the threads to hit the - # breakpoint. - sleep 1 - set running_count 0 set interrupted 0 gdb_test_multiple "info threads" "all threads running" { @@ -219,7 +255,8 @@ proc test {condition_eval target_non_stop non_stop displaced} { } } -re "$::gdb_prompt $" { - gdb_assert {$running_count == ($n_threads + 1) * 2} $gdb_test_name + gdb_assert {$running_count == ($::n_threads + 1) * 2} \ + $gdb_test_name } } @@ -292,7 +329,8 @@ foreach_with_prefix breakpoint-condition-evaluation {"host" "target"} { } foreach_with_prefix displaced {"off" "auto"} { - test ${breakpoint-condition-evaluation} ${target-non-stop} ${non-stop} ${displaced} + test_detach_command ${breakpoint-condition-evaluation} \ + ${target-non-stop} ${non-stop} ${displaced} } } } From patchwork Mon Nov 28 18:40:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61186 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 80C023845189 for ; Mon, 28 Nov 2022 18:42:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80C023845189 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660922; bh=vrYtTk2Z8YKPRU0QGmXf4IFuu2vmQUBGZW2LA/Dz69Q=; 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=NU9zO6dzTb6zZAnDnnlLjQa1pQs74+NAgu6QKSOVJkftAKkOasYjkqAN6M4uVTHod C8du7Yis70m1A6mxszlfAlSGaPb4G2rwrCWJt+ilx4j7UiS27bi1yp2rL3ZKandPw5 oFy/e7Qe1QEGJ0S8y7h3R5Q2NpWvd7j/E9MgCkfg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 201B3385703F for ; Mon, 28 Nov 2022 18:40:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 201B3385703F X-ASG-Debug-ID: 1669660846-0c856e02a043f3b0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id py3R8CYZBmuvYstm (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:46 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 9474B441D66; Mon, 28 Nov 2022 13:40:46 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Andrew Burgess , Simon Marchi Subject: [PATCH gdb-12-branch 4/6] gdb: fix assert when quitting GDB while a thread is stepping Date: Mon, 28 Nov 2022 13:40:40 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 4/6] gdb: fix assert when quitting GDB while a thread is stepping Message-Id: <20221128184042.3781569-5-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660846 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 6932 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Andrew Burgess This commit addresses one of the issues identified in PR gdb/28275. Bug gdb/28275 identifies a number of situations in which this assert: Assertion `!proc_target->commit_resumed_state' failed. could be triggered. There's actually a number of similar places where this assert is found in GDB, the two of interest in gdb/28275 are in target_wait and target_stop. In one of the comments: https://sourceware.org/bugzilla/show_bug.cgi?id=28275#c1 steps to trigger the assertion within target_stop were identified when using a modified version of the gdb.threads/detach-step-over.exp test script. In the gdb.threads/detach-step-over.exp test, we attach to a multi-threaded inferior, and continue the inferior in asynchronous (background) mode. Each thread is continuously hitting a conditional breakpoint where the condition is always false. While the inferior is running we detach. The goal is that we detach while GDB is performing a step-over for the conditional breakpoint in at least one thread. While detaching, if a step-over is in progress, then GDB has to complete the step over before we can detach. This involves calling target_stop and target_wait (see prepare_for_detach). As far as gdb/28275 is concerned, the interesting part here, is the the process_stratum_target::commit_resumed_state variable must be false when target_stop and target_wait are called. This is currently ensured because, in detach_command (infrun.c), we create an instance of scoped_disable_commit_resumed, this ensures that when target_detach is called, ::commit_resumed_state will be false. The modification to the test that I propose here, and which exposed the bug, is that, instead of using "detach" to detach from the inferior, we instead use "quit". Quitting GDB after attaching to an inferior will cause GDB to first detach, and then exit. When we quit GDB we end up calling target_detach via a different code path, the stack looks like: #0 target_detach #1 kill_or_detach #2 quit_force #3 quit_command Along this path there is no scoped_disable_commit_resumed created. ::commit_resumed_state can be true when we reach prepare_for_detach, which calls target_wait and target_stop, so the assertion will trigger. In this commit, I propose fixing this by adding the creation of a scoped_disable_commit_resumed into target_detach. This will ensure that ::commit_resumed_state is false when calling prepare_for_detach from within target_detach. I did consider placing the scoped_disable_commit_resumed in prepare_for_detach, however, placing it in target_detach ensures that the target's commit_resumed_state flag is left to false if the detached inferior was the last one for that target. It's the same rationale as for patch "gdb: disable commit resumed in target_kill" that comes later in this series, but for detach instead of kill. detach_command still includes a scoped_disable_commit_resumed too, but I think it is still relevant to cover the resumption at the end of the function. Co-Authored-By: Simon Marchi Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28275 Change-Id: Ie128f7aba6ef0e018859275eca372e6ea738e96f --- gdb/target.c | 5 ++ .../gdb.threads/detach-step-over.exp | 52 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/gdb/target.c b/gdb/target.c index 1ee051b520a..0c86b571e1c 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2558,6 +2558,9 @@ target_preopen (int from_tty) void target_detach (inferior *inf, int from_tty) { + /* Thread's don't need to be resumed until the end of this function. */ + scoped_disable_commit_resumed disable_commit_resumed ("detaching"); + /* After we have detached, we will clear the register cache for this inferior by calling registers_changed_ptid. We must save the pid_ptid before detaching, as the target detach method will clear inf->pid. */ @@ -2588,6 +2591,8 @@ target_detach (inferior *inf, int from_tty) inferior_ptid matches save_pid_ptid, but in our case, it does not call it, as inferior_ptid has been reset. */ reinit_frame_cache (); + + disable_commit_resumed.reset_and_commit (); } void diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp index ad9b08f549e..d2cb52423d9 100644 --- a/gdb/testsuite/gdb.threads/detach-step-over.exp +++ b/gdb/testsuite/gdb.threads/detach-step-over.exp @@ -284,6 +284,56 @@ proc_with_prefix test_detach_command {condition_eval target_non_stop non_stop di kill_wait_spawned_process $test_spawn_id } +# Similar to the proc above, but this time, instead of detaching using +# the 'detach' command, we quit GDB, this will also trigger a detach, but +# through a slightly different path, which can expose different bugs. +proc_with_prefix test_detach_quit {condition_eval target_non_stop \ + non_stop displaced} { + # If debugging with target remote, check whether the all-stop variant + # of the RSP is being used. If so, we can't run the background tests. + if {!$non_stop + && [target_info exists gdb_protocol] + && ([target_info gdb_protocol] == "remote" + || [target_info gdb_protocol] == "extended-remote")} { + start_gdb_for_test $condition_eval $target_non_stop \ + $non_stop $displaced + + gdb_test_multiple "maint show target-non-stop" "" { + -wrap -re "(is|currently) on.*" { + } + -wrap -re "(is|currently) off.*" { + return + } + } + } + + set test_spawn_id [spawn_wait_for_attach $::binfile] + set testpid [spawn_id_get_pid $test_spawn_id] + + set attempts 3 + for {set attempt 1} { $attempt <= $attempts } { incr attempt } { + with_test_prefix "iter $attempt" { + + start_gdb_for_test $condition_eval $target_non_stop \ + $non_stop $displaced + + if {![prepare_test_iter $testpid $non_stop \ + $attempt $attempts "$::decimal"]} { + kill_wait_spawned_process $test_spawn_id + return + } + + gdb_test_multiple "with confirm off -- quit" "" { + eof { + pass $gdb_test_name + } + } + } + } + + kill_wait_spawned_process $test_spawn_id +} + # The test program exits after a while, in case GDB crashes. Make it # wait at least as long as we may wait before declaring a time out # failure. @@ -331,6 +381,8 @@ foreach_with_prefix breakpoint-condition-evaluation {"host" "target"} { foreach_with_prefix displaced {"off" "auto"} { test_detach_command ${breakpoint-condition-evaluation} \ ${target-non-stop} ${non-stop} ${displaced} + test_detach_quit ${breakpoint-condition-evaluation} \ + ${target-non-stop} ${non-stop} ${displaced} } } } From patchwork Mon Nov 28 18:40:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61185 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 07B9B38493F1 for ; Mon, 28 Nov 2022 18:42:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 07B9B38493F1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660920; bh=FclHDsjzu7N/XvR1Jz8ctBb1KOX45KaooHvErXqun5w=; 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=vQtN2u2riZgk6mzLnfnZdySjCyTkyw2yGdQTWpcEpGh6jFqd5wqR5pZ35HpfmgtZ4 sbGlEZXWuUpPKUozIGIlkiN699sFB44gzqzowSeo6JTE6SBRq0R+J3IJyD0OApJJxk qoxa65Wm5s5MzNULyfqe3hBzWqntF955kr0WN23g= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 49670385516D for ; Mon, 28 Nov 2022 18:41:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 49670385516D X-ASG-Debug-ID: 1669660847-0c856e02a143f5a0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id UESUp8bRaZj6kKds (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:47 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 04006441D68; Mon, 28 Nov 2022 13:40:47 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH gdb-12-branch 5/6] gdbserver: switch to right process in find_one_thread Date: Mon, 28 Nov 2022 13:40:41 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 5/6] gdbserver: switch to right process in find_one_thread Message-Id: <20221128184042.3781569-6-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660847 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 11958 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests=WEIRD_PORT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 WEIRD_PORT URI: Uses non-standard port number for HTTP X-Spam-Status: No, score=-3498.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP, WEIRD_PORT 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" New in this version: add a dedicated test. When I do this: $ ./gdb -nx --data-directory=data-directory -q \ /bin/sleep \ -ex "maint set target-non-stop on" \ -ex "tar ext :1234" \ -ex "set remote exec-file /bin/sleep" \ -ex "run 1231 &" \ -ex add-inferior \ -ex "inferior 2" Reading symbols from /bin/sleep... (No debugging symbols found in /bin/sleep) Remote debugging using :1234 Starting program: /bin/sleep 1231 Reading /lib64/ld-linux-x86-64.so.2 from remote target... warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead. Reading /lib64/ld-linux-x86-64.so.2 from remote target... Reading /usr/lib/debug/.build-id/a6/7a1408f18db3576757eea210d07ba3fc560dff.debug from remote target... [New inferior 2] Added inferior 2 on connection 1 (extended-remote :1234) [Switching to inferior 2 [] ()] (gdb) Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target... attach 3659848 Attaching to process 3659848 /home/smarchi/src/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed. Note the "attach" command just above. When doing it on the command-line with a -ex switch, the bug doesn't trigger. The internal error of GDB is actually caused by GDBserver crashing, and the error recovery of GDB is not on point. This patch aims to fix just the GDBserver crash, not the GDB problem. GDBserver crashes with a segfault here: (gdb) bt #0 0x00005555557fb3f4 in find_one_thread (ptid=...) at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:177 #1 0x00005555557fd5cf in thread_db_thread_handle (ptid=, handle=0x7fffffffc400, handle_len=0x7fffffffc3f0) at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:461 #2 0x000055555578a0b6 in linux_process_target::thread_handle (this=0x5555558a64c0 , ptid=, handle=0x7fffffffc400, handle_len=0x7fffffffc3f0) at /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:6905 #3 0x00005555556dfcc6 in handle_qxfer_threads_worker (thread=0x60b000000510, buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1645 #4 0x00005555556e00e6 in operator() (__closure=0x7fffffffc5e0, thread=0x60b000000510) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1696 #5 0x00005555556f54be in for_each_thread >(struct {...}) (func=...) at /home/smarchi/src/binutils-gdb/gdbserver/gdbthread.h:159 #6 0x00005555556e0242 in handle_qxfer_threads_proper (buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1694 #7 0x00005555556e04ba in handle_qxfer_threads (annex=0x629000000213 "", readbuf=0x621000019100 '\276' ..., writebuf=0x0, offset=0, len=4097) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1732 #8 0x00005555556e1989 in handle_qxfer (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2045 #9 0x00005555556e720a in handle_query (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2685 #10 0x00005555556f1a01 in process_serial_event () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4176 #11 0x00005555556f4457 in handle_serial_event (err=0, client_data=0x0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4514 #12 0x0000555555820f56 in handle_file_event (file_ptr=0x607000000250, ready_mask=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573 #13 0x0000555555821895 in gdb_wait_for_event (block=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 #14 0x000055555581f533 in gdb_do_one_event (mstimeout=-1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:264 #15 0x00005555556ec9fb in start_event_loop () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3512 #16 0x00005555556f0769 in captured_main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3992 #17 0x00005555556f0e3f in main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4078 The reason is a wrong current process when find_one_thread is called. The current process is the 2nd one, which was just attached. It does not yet have thread_db data (proc->priv->thread_db is nullptr). As we iterate on all threads of all process to fulfull the qxfer:threads:read request, we get to a thread of process 1 for which we haven't read thread_db information yet (lwp_info::thread_known is false), so we get into find_one_thread. find_one_thread uses `current_process ()->priv->thread_db`, assuming the current process matches the ptid passed as a parameter, which is wrong. A segfault happens when trying to dereference that thread_db pointer. Fix this by making find_one_thread not assume what the current process / current thread is. If it needs to call into libthread_db, which we know will try to read memory from the current process, then temporarily set the current process. In the case where the thread is already know and we return early, we don't need to switch process. Add a test to reproduce this specific situation. Change-Id: I09b00883e8b73b7e5f89d0f47cb4e9c0f3d6caaa Approved-By: Andrew Burgess --- .../gdb.multi/attach-while-running.c | 26 +++++++ .../gdb.multi/attach-while-running.exp | 73 +++++++++++++++++++ gdbserver/thread-db.cc | 29 +++++--- 3 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 gdb/testsuite/gdb.multi/attach-while-running.c create mode 100644 gdb/testsuite/gdb.multi/attach-while-running.exp diff --git a/gdb/testsuite/gdb.multi/attach-while-running.c b/gdb/testsuite/gdb.multi/attach-while-running.c new file mode 100644 index 00000000000..dd321dfe007 --- /dev/null +++ b/gdb/testsuite/gdb.multi/attach-while-running.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2022 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 . */ + +#include + +int global_var = 123; + +int +main (void) +{ + sleep (30); +} diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp new file mode 100644 index 00000000000..125273d0524 --- /dev/null +++ b/gdb/testsuite/gdb.multi/attach-while-running.exp @@ -0,0 +1,73 @@ +# Copyright 2022 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 . + +# This test was introduced to reproduce a specific bug in GDBserver, where +# attaching an inferior while another one was running would trigger a segfault +# in GDBserver. Reproducing the bug required specific circumstances: +# +# - The first process must be far enough to have loaded its libc or +# libpthread (whatever triggers the loading of libthread_db), such that +# its proc->priv->thread_db is not nullptr +# +# - However, its lwp must still be in the `!lwp->thread_known` state, +# meaning GDBserver hasn't asked libthread_db to compute the thread +# handle yet. That means, GDB must not have refreshed the thread list +# yet, since that would cause the thread handles to be computed. That +# means, no stopping on a breakpoint, since that causes a thread list +# update. That's why the first inferior needs to be started with "run +# &". +# +# - Attaching the second process would segfault GDBserver. +# +# All of this to say, if modifying this test, please keep in mind the original +# intent. + +standard_testfile + +if [use_gdb_stub] { + unsupported "test requires running" + return +} + +if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +proc do_test {} { + save_vars { $::GDBFLAGS } { + append ::GDBFLAGS " -ex \"maint set target-non-stop on\"" + clean_restart $::binfile + } + + gdb_test_multiple "run &" "" { + -re ".*$::gdb_prompt " { + pass $gdb_test_name + } + } + gdb_test "add-inferior" "Added inferior 2 on connection 1 .*" + gdb_test "inferior 2" "Switching to inferior 2 .*" + + set spawn_id [spawn_wait_for_attach $::binfile] + set pid [spawn_id_get_pid $spawn_id] + + # This call would crash GDBserver. + gdb_attach $pid + + # Read a variable from the inferior, just to make sure the attach worked + # fine. + gdb_test "print global_var" " = 123" +} + +do_test diff --git a/gdbserver/thread-db.cc b/gdbserver/thread-db.cc index 6e0e2228a5f..bf98ca9557a 100644 --- a/gdbserver/thread-db.cc +++ b/gdbserver/thread-db.cc @@ -155,30 +155,35 @@ thread_db_state_str (td_thr_state_e state) } #endif -/* Get thread info about PTID, accessing memory via the current - thread. */ +/* Get thread info about PTID. */ static int find_one_thread (ptid_t ptid) { - td_thrhandle_t th; - td_thrinfo_t ti; - td_err_e err; - struct lwp_info *lwp; - struct thread_db *thread_db = current_process ()->priv->thread_db; - int lwpid = ptid.lwp (); - thread_info *thread = find_thread_ptid (ptid); - lwp = get_thread_lwp (thread); + lwp_info *lwp = get_thread_lwp (thread); if (lwp->thread_known) return 1; - /* Get information about this thread. */ - err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, &th); + /* Get information about this thread. libthread_db will need to read some + memory, which will be done on the current process, so make PTID's process + the current one. */ + process_info *proc = find_process_pid (ptid.pid ()); + gdb_assert (proc != nullptr); + + scoped_restore_current_thread restore_thread; + switch_to_process (proc); + + thread_db *thread_db = proc->priv->thread_db; + td_thrhandle_t th; + int lwpid = ptid.lwp (); + td_err_e err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, + &th); if (err != TD_OK) error ("Cannot get thread handle for LWP %d: %s", lwpid, thread_db_err_str (err)); + td_thrinfo_t ti; err = thread_db->td_thr_get_info_p (&th, &ti); if (err != TD_OK) error ("Cannot get thread info for LWP %d: %s", From patchwork Mon Nov 28 18:40:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61184 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 9E4AF38518AB for ; Mon, 28 Nov 2022 18:41:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9E4AF38518AB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669660911; bh=B8eXxZhLaxzVWVoAeM5WwuyGhGznhq47JIDs/+FDPTQ=; 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=ZxLlV1abo6YBSN12xd4X4h46tYRHi6HKg9Tyxosq/2xbphEeKcIhyC5XQKr449DPR FAnMyBkVfJAsVoCzA4sKJuHr7maxVsKp/lVGaDdjMuLCO6m0WtAjUA7z+ggzEK9uUS qf+bkRk7/VMSPBA1N13oTJ2/hqNrwJ99jBGxNdTY= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 884F03855155 for ; Mon, 28 Nov 2022 18:41:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 884F03855155 X-ASG-Debug-ID: 1669660847-0c856e02a043f3c0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id erEa66FsiNC1FlS8 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Mon, 28 Nov 2022 13:40:47 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 631B5441D65; Mon, 28 Nov 2022 13:40:47 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH gdb-12-branch 6/6] gdb: disable commit resumed in target_kill Date: Mon, 28 Nov 2022 13:40:42 -0500 X-ASG-Orig-Subj: [PATCH gdb-12-branch 6/6] gdb: disable commit resumed in target_kill Message-Id: <20221128184042.3781569-7-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221128184042.3781569-1-simon.marchi@efficios.com> References: <20221128184042.3781569-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1669660847 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 11734 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests=WEIRD_PORT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 WEIRD_PORT URI: Uses non-standard port number for HTTP X-Spam-Status: No, score=-3495.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPAM_BODY, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP, WEIRD_PORT 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: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" New in this version: - Better comment in target_kill - Uncomment line in test to avoid hanging when exiting, when testing on native-extended-gdbserver PR 28275 shows that doing a sequence of: - Run inferior in background (run &) - kill that inferior - Run again We get into this assertion: /home/smarchi/src/binutils-gdb/gdb/target.c:2590: internal-error: target_wait: Assertion `!proc_target->commit_resumed_state' failed. #0 internal_error_loc (file=0x5606b344e740 "/home/smarchi/src/binutils-gdb/gdb/target.c", line=2590, fmt=0x5606b344d6a0 "%s: Assertion `%s' failed.") at /home/smarchi/src/binutils-gdb/gdbsupport/errors.cc:54 #1 0x00005606b6296475 in target_wait (ptid=..., status=0x7fffb9390630, options=...) at /home/smarchi/src/binutils-gdb/gdb/target.c:2590 #2 0x00005606b5767a98 in startup_inferior (proc_target=0x5606bfccb2a0 , pid=3884857, ntraps=1, last_waitstatus=0x0, last_ptid=0x0) at /home/smarchi/src/binutils-gdb/gdb/nat/fork-inferior.c:482 #3 0x00005606b4e6c9c5 in gdb_startup_inferior (pid=3884857, num_traps=1) at /home/smarchi/src/binutils-gdb/gdb/fork-child.c:132 #4 0x00005606b50f14a5 in inf_ptrace_target::create_inferior (this=0x5606bfccb2a0 , exec_file=0x604000039f50 "/home/smarchi/build/binutils-gdb/gdb/test", allargs="", env=0x61500000a580, from_tty=1) at /home/smarchi/src/binutils-gdb/gdb/inf-ptrace.c:105 #5 0x00005606b53b6d23 in linux_nat_target::create_inferior (this=0x5606bfccb2a0 , exec_file=0x604000039f50 "/home/smarchi/build/binutils-gdb/gdb/test", allargs="", env=0x61500000a580, from_tty=1) at /home/smarchi/src/binutils-gdb/gdb/linux-nat.c:978 #6 0x00005606b512b79b in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at /home/smarchi/src/binutils-gdb/gdb/infcmd.c:468 #7 0x00005606b512c236 in run_command (args=0x0, from_tty=1) at /home/smarchi/src/binutils-gdb/gdb/infcmd.c:526 When running the kill command, commit_resumed_state for the process_stratum_target (linux-nat, here) is true. After the kill, when there are no more threads, commit_resumed_state is still true, as nothing touches this flag during the kill operation. During the subsequent run command, run_command_1 does: scoped_disable_commit_resumed disable_commit_resumed ("running"); We would think that this would clear the commit_resumed_state flag of our native target, but that's not the case, because scoped_disable_commit_resumed iterates on non-exited inferiors in order to find active process targets. And after the kill, the inferior is exited, and the native target was unpushed from it anyway. So scoped_disable_commit_resumed doesn't touch the commit_resumed_state flag of the native target, it stays true. When reaching target_wait, in startup_inferior (to consume the initial expect stop events while the inferior is starting up and working its way through the shell), commit_resumed_state is true, breaking the contract saying that commit_resumed_state is always false when calling the targets' wait method. (note: to be correct, I think that startup_inferior should toggle commit_resumed between the target_wait and target_resume calls, but I'll ignore that for now) I can see multiple ways to fix this. In the end, we need commit_resumed_state to be cleared by the time we get to that target_wait. It could be done at the end of the kill command, or at the beginning of the run command. To keep things in a coherent state, I'd like to make it so that after the kill command, when the target is left with no threads, its commit_resumed_state flag is left to false. This way, we can keep working with the assumption that a target with no threads (and therefore no running threads) has commit_resumed_state == false. Do this by adding a scoped_disable_commit_resumed in target_kill. It clears the target's commit_resumed_state on entry, and leaves it false if the target does not have any resumed thread on exit. That means, even if the target has another inferior with stopped threads, commit_resumed_state will be left to false, which makes sense. Add a test that tries to cover various combinations of actions done while an inferior is running (and therefore while commit_resumed_state is true on the process target). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28275 Change-Id: I8e6fe6dc1f475055921520e58cab68024039a1e9 Approved-By: Andrew Burgess --- gdb/target.c | 9 ++ .../gdb.base/run-control-while-bg-execution.c | 33 +++++ .../run-control-while-bg-execution.exp | 122 ++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 gdb/testsuite/gdb.base/run-control-while-bg-execution.c create mode 100644 gdb/testsuite/gdb.base/run-control-while-bg-execution.exp diff --git a/gdb/target.c b/gdb/target.c index 0c86b571e1c..0eae5307785 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -908,6 +908,15 @@ add_deprecated_target_alias (const target_info &tinfo, const char *alias) void target_kill (void) { + + /* If the commit_resume_state of the to-be-killed-inferior's process stratum + is true, and this inferior is the last live inferior with resumed threads + of that target, then we want to leave commit_resume_state to false, as the + target won't have any resumed threads anymore. We achieve this with + this scoped_disable_commit_resumed. On construction, it will set the flag + to false. On destruction, it will only set it to true if there are resumed + threads left. */ + scoped_disable_commit_resumed disable ("killing"); current_inferior ()->top_target ()->kill (); } diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.c b/gdb/testsuite/gdb.base/run-control-while-bg-execution.c new file mode 100644 index 00000000000..8092fadc8b9 --- /dev/null +++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.c @@ -0,0 +1,33 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020-2022 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 . */ + // +#include + +static pid_t mypid = -1; + +static void +after_getpid (void) +{ +} + +int +main (void) +{ + mypid = getpid (); + after_getpid (); + sleep (30); +} diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp new file mode 100644 index 00000000000..5b4834f0b32 --- /dev/null +++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp @@ -0,0 +1,122 @@ +# Copyright 2022 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 . + +# This test aims at testing various operations after getting rid of an inferior +# that was running in background, or while we have an inferior running in +# background. The original intent was to expose cases where the commit-resumed +# state of the process stratum target was not reset properly after killing an +# inferior running in background, which would be a problem when trying to run +# again. The test was expanded to test various combinations of +# run-control-related actions done with an inferior running in background. + +if {[use_gdb_stub]} { + unsupported "test requires running" + return +} + +standard_testfile + +if {[build_executable "failed to prepare" $testfile $srcfile]} { + return +} + +# Run one variation of the test: +# +# 1. Start an inferior in the background with "run &" +# 2. Do action 1 +# 3. Do action 2 +# +# Action 1 indicates what to do with the inferior running in background: +# +# - kill: kill it +# - detach: detach it +# - add: add a new inferior and switch to it, leave the inferior running in +# background alone +# - none: do nothing, leave the inferior running in background alone +# +# Action 2 indicates what to do after that: +# +# - start: use the start command +# - run: use the run command +# - attach: start a process outside of GDB and attach it +proc do_test { action1 action2 } { + save_vars { ::GDBFLAGS } { + append ::GDBFLAGS " -ex \"maintenance set target-non-stop on\"" + clean_restart $::binfile + } + + # Ensure we are at least after the getpid call, should we need it. + if { ![runto "after_getpid"] } { + return + } + + # Some commands below ask for confirmation. Turn that off for simplicity. + gdb_test "set confirm off" + gdb_test_multiple "continue &" "" { + -re ".*\r\n$::gdb_prompt " { + pass $gdb_test_name + } + } + + if { $action1 == "kill" } { + gdb_test "kill" "Inferior 1 .* killed.*" + } elseif { $action1 == "detach" } { + set child_pid [get_integer_valueof "mypid" -1] + if { $child_pid == -1 } { + fail "failed to extract child pid" + return + } + + gdb_test "detach" "Inferior 1 .* detached.*" "detach from first instance" + + # Kill the detached process, to avoid hanging when exiting GDBserver, + # when testing with the native-extended-gdbserver board. + remote_exec target "kill $child_pid" + } elseif { $action1 == "add" } { + gdb_test "add-inferior -exec $::binfile" \ + "Added inferior 2 on connection 1.*" "add-inferior" + gdb_test "inferior 2" "Switching to inferior 2 .*" + } elseif { $action1 == "none" } { + + } else { + error "invalid action 1" + } + + if { $action2 == "start" } { + gdb_test "start" "Temporary breakpoint $::decimal\(?:\.$::decimal\)?, main .*" + } elseif { $action2 == "run" } { + gdb_test "break main" "Breakpoint $::decimal at $::hex.*" + gdb_test "run" "Breakpoint $::decimal\(?:\.$::decimal\)?, main .*" + } elseif { $action2 == "attach" } { + set test_spawn_id [spawn_wait_for_attach $::binfile] + set test_pid [spawn_id_get_pid $test_spawn_id] + + if { [gdb_attach $test_pid] } { + gdb_test "detach" "Inferior $::decimal .* detached.*" \ + "detach from second instance" + } + + # Detach and kill this inferior so we don't leave it around. + kill_wait_spawned_process $test_spawn_id + } else { + error "invalid action 2" + } +} + +foreach_with_prefix action1 { kill detach add none } { + foreach_with_prefix action2 { start run attach } { + do_test $action1 $action2 + } +}