From patchwork Mon Dec 23 19:29:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 37081 Received: (qmail 101149 invoked by alias); 23 Dec 2019 19:30:37 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 101084 invoked by uid 89); 23 Dec 2019 19:30:25 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_PASS autolearn=ham version=3.3.1 spammy=Switch, H*f:sk:2019101, exploits, sends X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-2.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Dec 2019 19:30:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1577129403; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wpu+/XJ4AHbY1zerNFSWj0ahNZlsF0i5MM1mH8g0HwM=; b=ZoamhkGhi7YeAaOVE7IfsiZ0Mu3rNCun6Y7rHZsl6qx7JesIRWC0tupNcLU9q8xIfyuvts yS9id5Hh8IpeUeYkMsmdeGajttB0vrAqa7b1W0dLBig6/70rScXFdn6EM9NDlflfpUL3YK 9oskvoz5ng9vAhZ8tHjCYSA22enbWYk= Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-299-j5Vu9aS3MWGwN9UYuWdvGw-1; Mon, 23 Dec 2019 14:30:01 -0500 Received: by mail-ed1-f71.google.com with SMTP id n63so11260583edc.20 for ; Mon, 23 Dec 2019 11:30:01 -0800 (PST) Return-Path: Received: from ?IPv6:2001:8a0:f913:f700:56ee:75ff:fe8d:232b? ([2001:8a0:f913:f700:56ee:75ff:fe8d:232b]) by smtp.gmail.com with ESMTPSA id j17sm2301753ejf.83.2019.12.23.11.29.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 23 Dec 2019 11:29:59 -0800 (PST) Subject: [PATCH] Switch the inferior too in switch_to_program_space_and_thread (Re: [PATCH v2 08/24] Introduce switch_to_inferior_no_thread) To: "Paunovic, Aleksandar" References: <20191017225026.30496-1-palves@redhat.com> <20191017225026.30496-9-palves@redhat.com> Cc: "gdb-patches@sourceware.org" From: Pedro Alves Message-ID: <489c25ee-b0ae-6a17-65cc-32c5d7c652d2@redhat.com> Date: Mon, 23 Dec 2019 19:29:57 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: X-Mimecast-Spam-Score: 0 On 12/20/19 6:50 PM, Pedro Alves wrote: > Oh wow, thanks much for this. You're right. I'm working on > converting your example above to a testsuite testcase. Here it is. I'm putting this at the end of the series, after the multi-target patches, because before multi-target, the test fails -- GDB sends a spurious Hg0.0 packet to the remote side. From 839bb32983d8afb085eeec1ac6ca499f5bbd6244 Mon Sep 17 00:00:00 2001 From: Aleksandar Paunovic Date: Mon, 23 Dec 2019 18:04:32 +0000 Subject: [PATCH] Switch the inferior too in switch_to_program_space_and_thread With multi-target, each inferior now has its own target connection. The problem in switch_to_program_space_and_thread is that in the current state GDB switches to "no thread" and also sets the program space but because the inferior is not switched, potentially an incorrect target remains selected. Here is a sample scenario that exploits this flow: On terminal 1, start a gdbserver on a program named foo: $ gdbserver :1234 ./foo On terminal 2, start gdb on a program named bar. Suppose foo and bar are compiled from foo.c and bar.c. They are completely separate. So, bar.c:2 has no meaning for foo. $ gdb -q ./bar Reading symbols from ./bar... (gdb) add-inferior [New inferior 2] Added inferior 2 (gdb) inferior 2 [Switching to inferior 2 [] ()] (gdb) target remote :1234 ... (gdb) set debug remote 2 (gdb) break bar.c:2 Sending packet: $Hgp0.0#ad...Packet received: OK Sending packet: $m5fa,12#f8...Packet received: E01 Sending packet: $m5fa,1#c6...Packet received: E01 Sending packet: $m5fb,3#c9...Packet received: E01 Sending packet: $m5fe,1#ca...Packet received: E01 Breakpoint 1 at 0x5fe: file bar.c, line 2. (gdb) Here we have an unnecessary sending of the packets to the gdbserver. With this fix in progspace-and-thread.c, we'll get this: (gdb) break bar.c:2 Breakpoint 1 at 0x5fe: file bar.c, line 2. (gdb) Now there is no sending of the packets to gdbserver. gdb/ChangeLog: yyyy-mm-dd Aleksandar Paunovic Pedro Alves * progspace-and-thread.c (switch_to_program_space_and_thread): Assert there's an inferior for PSPACE. Use switch_to_inferior_no_thread to switch the inferior too. gdb/testsuite/ChangeLog: yyyy-mm-dd Pedro Alves * gdb.server/bkpt-other-inferior.exp: New file. --- gdb/progspace-and-thread.c | 6 +- gdb/testsuite/gdb.server/bkpt-other-inferior.exp | 93 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 gdb/testsuite/gdb.server/bkpt-other-inferior.exp diff --git a/gdb/progspace-and-thread.c b/gdb/progspace-and-thread.c index 3c92b5c8e0..d51748035e 100644 --- a/gdb/progspace-and-thread.c +++ b/gdb/progspace-and-thread.c @@ -25,8 +25,9 @@ void switch_to_program_space_and_thread (program_space *pspace) { inferior *inf = find_inferior_for_program_space (pspace); + gdb_assert (inf != nullptr); - if (inf != NULL && inf->pid != 0) + if (inf->pid != 0) { thread_info *tp = any_live_thread_of_inferior (inf); @@ -39,6 +40,5 @@ switch_to_program_space_and_thread (program_space *pspace) } } - switch_to_no_thread (); - set_current_program_space (pspace); + switch_to_inferior_no_thread (inf); } diff --git a/gdb/testsuite/gdb.server/bkpt-other-inferior.exp b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp new file mode 100644 index 0000000000..e2a7be5cdb --- /dev/null +++ b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp @@ -0,0 +1,93 @@ +# Copyright 2019 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 . + +# Test that GDB does not access the remote target's memory when +# setting a breakpoint on a function that only exists in an inferior +# that is not bound to the remote target. + +load_lib gdbserver-support.exp + +standard_testfile server.c + +if { [skip_gdbserver_tests] } { + return 0 +} + +if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \ + {debug pthreads}] } { + return +} + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +# Leave inferior 1 with the exec target, not connected. Add another +# inferior, and connect it to gdbserver. + +gdb_test "add-inferior" "Added inferior 2" \ + "add inferior 2" +gdb_test "inferior 2" "Switching to inferior 2.*" \ + "switch to inferior 2" +gdb_test "file ${binfile}" ".*" "load file in inferior 2" + +set target_exec [gdbserver_download_current_prog] + +# Start GDBserver. +set res [gdbserver_start "" $target_exec] + +# Connect to GDBserver. +set gdbserver_protocol [lindex $res 0] +set gdbserver_gdbport [lindex $res 1] +gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport + +# Discard any symbol files that we have opened. +set test "discard symbol table" +gdb_test_multiple "file" $test { + -re "A program is being debugged already..*Are you sure you want to change the file.*y or n. $" { + gdb_test "y" ".*" $test \ + {Discard symbol table from `.*'\? \(y or n\) } "y" + } +} + +# At this point: +# +# - inferior 1 has symbols, and is not connected to any target. +# - inferior 2 has no symbols, and is connected to gdbserver. + +# Setting a breakpoint at some function by name should set a +# breakpoint on inferior 1, since it has symbols, and should not +# result in any access to inferior 2's remote target. + +gdb_test_no_output "set debug remote 1" + +foreach inf_sel {1 2} { + with_test_prefix "inf $inf_sel" { + gdb_test "inferior $inf_sel" "Switching to inferior $inf_sel.*" \ + "switch to inferior" + + set test "set breakpoint" + gdb_test_multiple "break main" $test { + -re "Sending packet.*$gdb_prompt $" { + fail $test + } + -re "^break main\r\nBreakpoint .* at .*$gdb_prompt $" { + pass $test + } + } + + delete_breakpoints + } +}