From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) by sourceware.org (Postfix) with ESMTPS id 8DC313857C5D for ; Thu, 10 Mar 2022 11:30:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8DC313857C5D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f44.google.com with SMTP id i8so7449594wrr.8 for ; Thu, 10 Mar 2022 03:30:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=eiiZ9lmqadEBuY1UONNNCJOwZCXMkJphVgWgyqxw33o=; b=4lcEgsJfqF6jHHhtoDQ+TXp9WIHb4dAogstFr0XalDa6Yvo1griAQoEOHNS6rUdx+V 1TAZgfuIiCriajPP0avzijPIt3Mc68XUVUfJ1htmCk+kFMvSsdGl/TtQqyAdIa8ru76p Nktq1rCBbKM8Xz9y/B0xNoHDuTpuFboqnWXqcTZ3cfejTzcJhR+SKEDfizZ0jKpows0Q juJCmD3StVLdiBXppCvSbr8iiFApacjVxE3fd3jQZlNr1ChILpEhM+rk2AE3Hn8D7UHf YnnmogZObGFuE6EYsXzrlJFZpfeDEtnmad2MyFag4glW8t83mLxtATpI5XgwHlVc/QnZ USAQ== X-Gm-Message-State: AOAM531Os773dRnfHq3IhoQkNMY5tTrjtg8lptJpAjMYK70rIDRU1JMg 4phMDbLZMVHDXUi0KE/hP1k= X-Google-Smtp-Source: ABdhPJwu+5tTz0os7XS1tjso836xtIypamMpkJa6//lnFQkXdOsNM6ajr2HjB6X3MDukcQ5C6SxF4g== X-Received: by 2002:adf:e802:0:b0:1ee:a1e5:bbeb with SMTP id o2-20020adfe802000000b001eea1e5bbebmr3221317wrm.112.1646911854249; Thu, 10 Mar 2022 03:30:54 -0800 (PST) Received: from ?IPV6:2001:8a0:f924:2600:209d:85e2:409e:8726? ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id f186-20020a1c38c3000000b00382a9b91515sm7481258wma.37.2022.03.10.03.30.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 10 Mar 2022 03:30:53 -0800 (PST) Message-ID: Date: Thu, 10 Mar 2022 11:30:51 +0000 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.6.1 Subject: Re: [EXT] Re: Semihosting in GDB 11.1 | Proposed patch for interrupting in sync mode Content-Language: en-US To: Adrian Oltean , Tom Tromey Cc: Adrian Oltean via Gdb References: <87k0d2gb44.fsf@tromey.com> From: Pedro Alves In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Mar 2022 11:30:57 -0000 On 2022-03-10 10:02, Adrian Oltean wrote: > As far as 'H' packet handling is concerned, note that the GDB server I'm referring is a proprietary implementation > that is used for JTAG debugging. Threads are numbered from 1. However, in the old implementation "Hg0" was always > switching to thread 1 ("first thread") internally, even though some other core/thread was suspended. The original > implementation assumed "Hg0" must *always* switch to "first thread" (thread 1 in my case) but this doesn't seem > to be enforced in the RSP specs. I updated the code and assimilate "arbitrary" (from spec) as "if there's no suspended > thread/core internally selected, find a valid one". So going back to your original problem description, you said: ~~~~ 2. File I/O (semihosting) when a multicore (ARMv8) target is involved seems to exhibit an issue. My multicore debugging model assumes that each core is a separate thread. If I have 'printf' calls executed on separate cores, I noticed that the messages are duplicated on secondary cores (other than core 0). The remote log snippet that highlights the root cause is pasted below. Long story short, the 'H' packet that is sent to the server and instructs it to use thread 0 for some further operations, actually causes troubles because breakpoint handling and run control gets broken afterwards. Note that the 'Fwrite' is the result of a 'printf' on a secondary core, thus instructing the server to use thread 0 breaks lots of things inside the GDB server. The 'H' packet seems to be sent as a result of the 'continue' action and it translates into a call to 'switch_to_no_thread'. If I ignore the 'H' packet, semihosting breakpoints and run control are correctly handled, so the second 'Fwrite' RSP sequence would not exist (this is the expected behavior). Is the described behavior a known issue inside GDB? Or do I have to change something in the server to correct the described behavior? [remote] Sending packet: $vCont;c#a8 [remote] Received Ack [remote] wait: enter [remote] Packet received: Fwrite,1,80026300,12 [remote] Sending packet: $Hg0#df [remote] Received Ack [remote] Packet received: OK [remote] Sending packet: $m80026300,12#8f [remote] Received Ack [remote] Packet received: 48656c6c6f2066726f6d20436f726523370a [remote] Sending packet: $F12#a9 [remote] Received Ack [remote] Packet received: Fwrite,1,80026300,12 [remote] Sending packet: $m80026300,12#8f [remote] Received Ack [remote] Packet received: 48656c6c6f2066726f6d20436f726523370a [remote] Sending packet: $F12#a9 [remote] Received Ack [remote] Packet received: T05thread:p1.8;core:7; [remote] wait: exit ~~~~ The printf calls end up calling write under the hood, of course, and those syscalls are intercepted and translated to File I/O calls into GDB. That's the "Fwrite,1,80026300,12" packets. Now, GDB processes those and writes to its own stdout. What is written to its stdout is 12 bytes found at 0x80026300 in the inferior memory, as per the Fwrite packet's arguments. Depending on the kind of target object is being accessed, GDB makes sure to select the proper remote thread, or at least any thread of the right remote process. This is important for when the remote side understands the multi-process extensions, for example, lest GDB reads something of the wrong process. So in remote.c, you'll see calls to set_general_process, like this: /* Make sure the remote is pointing at the right process. */ set_general_process (); ... which translate to "HgPID.0" when multi-process extensions are supported by the server, and "Hg0" when they're not. For memory reads in particular, GDB instead makes sure that GDB's selected thread is selected on the server side as well, not just any thread of the gdb-selected process. This is done here: enum target_xfer_status remote_target::xfer_partial (enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { ... set_general_thread (inferior_ptid); So what I think is happening is that inferior_ptid is null_ptid when you get here. We always switch to null_ptid when waiting for events out of the target, exactly to better uncover spots that would be relying on some stale non-null inferior_ptid by accident. This would be such a case. The inferior is running, and we're waiting for events, so whatever was the gdb-selected thread (per inferior_ptid) has no bearing on what thread is reporting some event. If the server supports multi-process extensions, then that set_general_thread call above with inferior_ptid == null_ptid will end up sending "Hg0.0", meaning, select any thread of any process, which means the subsequent memory read (m packet) will potentially read memory off of the wrong process. This is obviously bad. HOWEVER. Note that the File I/O packets, like "Fwrite,1,80026300,12" don't say at all which thread is doing the File I/O access! IOW, this packet is not useable in multi-process scenarios as is... It would need to be extended to also pass down an extra thread id field, like "Fwrite,1,80026300,12,pPID.TID". FSF GDBserver doesn't support File I/O, so these File I/O packets didn't get attention when the multi-process extensions were devised. So alright, the current "Hg0" packet you see in your logs is a bit spurious, but, it should be harmless, and you should be able to select any valid thread, as per the Hg0 packet's description, as all threads share the same address space, in GDB's view. [remote] Packet received: Fwrite,1,80026300,12 [remote] Sending packet: $Hg0#df [remote] Received Ack [remote] Packet received: OK [remote] Sending packet: $m80026300,12#8f [remote] Received Ack [remote] Packet received: 48656c6c6f2066726f6d20436f726523370a [remote] Sending packet: $F12#a9 What I think you should do is, when you get the reply to Fwrite -- the "$F12#a9" packet -- your stub should make sure that that resumes the same thread that initiated the Fwrite, not whatever Hg selected. That $F12 reply is linked with the last Fwrite, there can only be one File I/O request ongoing at a given time. Pedro Alves