| Message ID | 20221212203101.1034916-15-pedro@palves.net |
|---|---|
| State | New |
| Headers |
Return-Path: <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> 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 8018B3864A02 for <patchwork@sourceware.org>; Mon, 12 Dec 2022 20:32:44 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by sourceware.org (Postfix) with ESMTPS id E0BBF384D3EC for <gdb-patches@sourceware.org>; Mon, 12 Dec 2022 20:31:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E0BBF384D3EC 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-f49.google.com with SMTP id h16so4490527wrz.12 for <gdb-patches@sourceware.org>; Mon, 12 Dec 2022 12:31:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NCl5SuJ6M0OdQ0mnCN7bP7wb/GguN+7mcZayHYLvvaY=; b=iJMsy+XbSu1aO1hAk91OiyuRrTwKKsI0EeubDEZqmQWeaSYIyjBKWASIyu78aFKvOd elBlC3C0C30GFEsxYK0VrQn7exaIwkMRvd4oMDqDgnGve6gb3kRKh3TG3i4iPLtpwSPW qdwWD9uNvW+IiAbChFecXSaBmtixZ8sdFcqaCx4cLsmdHYcr/kfqLTpXXr5Z+pMWd7H0 AFMg7/qs+L2C0WA+0gNHx8sro+vyT5JZDY9yVUL7/VFoqyLiC/7Qv1tgmBUfbyIZmlF+ yU005qcW0cxb3qjArTgX3mtBJA3B+t3yUYE/qn4aPDTXisAvW+qDQqlgKqjAzbfhBtiY 3n/A== X-Gm-Message-State: ANoB5plcYdKEP5VDlWoLdKPF1ORis4Rtup0e6z8kWo6VBBM3Plt4GS/d qAouWz1WCSCe7aWm51f7d189FN3w7Y+VWA== X-Google-Smtp-Source: AA0mqf6VUMineUzIhcDwYIGR2NYFZqpflLhnjjfoN1BihJPTs4IpDfCe5CR4oJSiuqYoaiugOeLEFg== X-Received: by 2002:a5d:54c8:0:b0:242:19b1:bfae with SMTP id x8-20020a5d54c8000000b0024219b1bfaemr13245226wrv.53.1670877076826; Mon, 12 Dec 2022 12:31:16 -0800 (PST) Received: from localhost ([2001:8a0:f912:6700:afd9:8b6d:223f:6170]) by smtp.gmail.com with ESMTPSA id bj5-20020a0560001e0500b002362f6fcaf5sm10125202wrb.48.2022.12.12.12.31.16 for <gdb-patches@sourceware.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 12 Dec 2022 12:31:16 -0800 (PST) From: Pedro Alves <pedro@palves.net> To: gdb-patches@sourceware.org Subject: [PATCH 14/31] all-stop/synchronous RSP support thread-exit events Date: Mon, 12 Dec 2022 20:30:44 +0000 Message-Id: <20221212203101.1034916-15-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20221212203101.1034916-1-pedro@palves.net> References: <20221212203101.1034916-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.3 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, 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 <gdb-patches.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=subscribe> Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> |
| Series |
Step over thread clone and thread exit
|
|
Commit Message
Pedro Alves
Dec. 12, 2022, 8:30 p.m. UTC
Currently, GDB does not understand the THREAD_EXITED stop reply in remote all-stop mode. There's no good reason for this, it just happened that THREAD_EXITED was only ever reported in non-stop mode so far. This patch teaches GDB to parse that event in all-stop RSP too. There is no need to add a qSupported feature for this, because the server won't send a THREAD_EXITED event unless GDB explicitly asks for it, with QThreadEvents, or with the GDB_THREAD_OPTION_EXIT QThreadOptions option added in the next patch. Change-Id: Ide5d12391adf432779fe4c79526801c4a5630966 --- gdb/remote.c | 5 +++-- gdbserver/server.cc | 1 + 2 files changed, 4 insertions(+), 2 deletions(-)
Comments
Pedro Alves <pedro@palves.net> writes: > Currently, GDB does not understand the THREAD_EXITED stop reply in > remote all-stop mode. There's no good reason for this, it just > happened that THREAD_EXITED was only ever reported in non-stop mode so > far. This patch teaches GDB to parse that event in all-stop RSP too. > There is no need to add a qSupported feature for this, because the > server won't send a THREAD_EXITED event unless GDB explicitly asks for > it, with QThreadEvents, or with the GDB_THREAD_OPTION_EXIT > QThreadOptions option added in the next patch. > > Change-Id: Ide5d12391adf432779fe4c79526801c4a5630966 > --- > gdb/remote.c | 5 +++-- > gdbserver/server.cc | 1 + > 2 files changed, 4 insertions(+), 2 deletions(-) > > diff --git a/gdb/remote.c b/gdb/remote.c > index 9de8ed8a068..f7ab8523fd5 100644 > --- a/gdb/remote.c > +++ b/gdb/remote.c > @@ -8172,7 +8172,8 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, > && status->kind () != TARGET_WAITKIND_NO_RESUMED) > { > /* Expedited registers. */ > - if (!stop_reply->regcache.empty ()) > + if (status->kind () != TARGET_WAITKIND_THREAD_EXITED > + && !stop_reply->regcache.empty ()) I haven't investigated if this crops up, but, inside the if block we call xfree to release some of the regcache data. If it was ever the case the status->kind() was THREAD_EXITED, and the regcache was not empty, would we then leak memory? If THREAD_EXITED implies that the regcache is empty could we use an assert here instead of adding the kind check to the if? Maybe: if (!stop_reply->regcache.empty ()) { gdb_assert (status->kind () != TARGET_WAITKIND_THREAD_EXITED); ... But maybe that's bad because we'd be making assert based on state that arrives from gdbserver. In which case, should we perform some action to ensure that the regcache data is correctly freed? Thanks, Andrew > { > struct regcache *regcache > = get_thread_arch_regcache (this, ptid, stop_reply->arch); > @@ -8358,7 +8359,7 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status, > again. Keep waiting for events. */ > rs->waiting_for_stop_reply = 1; > break; > - case 'N': case 'T': case 'S': case 'X': case 'W': > + case 'N': case 'T': case 'S': case 'X': case 'W': case 'w': > { > /* There is a stop reply to handle. */ > rs->waiting_for_stop_reply = 0; > diff --git a/gdbserver/server.cc b/gdbserver/server.cc > index 07a3319d114..5099db1ee31 100644 > --- a/gdbserver/server.cc > +++ b/gdbserver/server.cc > @@ -3061,6 +3061,7 @@ resume (struct thread_resume *actions, size_t num_actions) > > if (cs.last_status.kind () != TARGET_WAITKIND_EXITED > && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED > + && cs.last_status.kind () != TARGET_WAITKIND_THREAD_EXITED > && cs.last_status.kind () != TARGET_WAITKIND_NO_RESUMED) > current_thread->last_status = cs.last_status; > > -- > 2.36.0
On 2023-06-07 18:52, Andrew Burgess wrote: > Pedro Alves <pedro@palves.net> writes: > >> Currently, GDB does not understand the THREAD_EXITED stop reply in >> remote all-stop mode. There's no good reason for this, it just >> happened that THREAD_EXITED was only ever reported in non-stop mode so >> far. This patch teaches GDB to parse that event in all-stop RSP too. >> There is no need to add a qSupported feature for this, because the >> server won't send a THREAD_EXITED event unless GDB explicitly asks for >> it, with QThreadEvents, or with the GDB_THREAD_OPTION_EXIT >> QThreadOptions option added in the next patch. >> >> Change-Id: Ide5d12391adf432779fe4c79526801c4a5630966 >> --- >> gdb/remote.c | 5 +++-- >> gdbserver/server.cc | 1 + >> 2 files changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/gdb/remote.c b/gdb/remote.c >> index 9de8ed8a068..f7ab8523fd5 100644 >> --- a/gdb/remote.c >> +++ b/gdb/remote.c >> @@ -8172,7 +8172,8 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, >> && status->kind () != TARGET_WAITKIND_NO_RESUMED) >> { >> /* Expedited registers. */ >> - if (!stop_reply->regcache.empty ()) >> + if (status->kind () != TARGET_WAITKIND_THREAD_EXITED >> + && !stop_reply->regcache.empty ()) > > I haven't investigated if this crops up, but, inside the if block we > call xfree to release some of the regcache data. > > If it was ever the case the status->kind() was THREAD_EXITED, and the > regcache was not empty, would we then leak memory? THREAD_EXITED stop replies can't carry expedited registers, they're not a kind of T stop reply, they're their own stop reply kind. They're just: @anchor{thread exit event} @cindex thread exit event, remote reply @item w @var{AA} ; @var{tid} The thread exited, and @var{AA} is the exit status. This response should not be sent by default; @value{GDBN} requests it with the @ref{QThreadEvents} packet. See also @ref{thread create event} above. @var{AA} is formatted as a big-endian hex string. But even if a remote server included them somehow, we wouldn't parse them: case 'w': /* Thread exited. */ { ULONGEST value; p = unpack_varlen_hex (&buf[1], &value); event->ws.set_thread_exited (value); if (*p != ';') error (_("stop reply packet badly formatted: %s"), buf); event->ptid = read_ptid (++p, NULL); break; } I don't remember exactly why I added the "status->kind () != TARGET_WAITKIND_THREAD_EXITED" check, I think it was just because I was reading the code and noticed it doesn't make sense to process expected registers for that event. > > If THREAD_EXITED implies that the regcache is empty could we use an > assert here instead of adding the kind check to the if? Maybe: > > if (!stop_reply->regcache.empty ()) > { > gdb_assert (status->kind () != TARGET_WAITKIND_THREAD_EXITED); > > ... > Makes sense, I did this. > But maybe that's bad because we'd be making assert based on state that > arrives from gdbserver. As explained above, that can't happen, so an assertion is fine. > In which case, should we perform some action to > ensure that the regcache data is correctly freed? I wrote a couple patches to improve ownership around this, using unique_ptr more. I will post them after this series (need to write commit logs, etc.)
Hi! On 2023-11-13 14:11, Pedro Alves wrote: > On 2023-06-07 18:52, Andrew Burgess wrote: >> In which case, should we perform some action to >> ensure that the regcache data is correctly freed? > > I wrote a couple patches to improve ownership around this, using > unique_ptr more. I will post them after this series (need to write > commit logs, etc.) > I finally sent patches for this: [PATCH 0/2] Use unique_ptr more in the remote target https://sourceware.org/pipermail/gdb-patches/2023-December/205179.html Pedro Alves
diff --git a/gdb/remote.c b/gdb/remote.c index 9de8ed8a068..f7ab8523fd5 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -8172,7 +8172,8 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, && status->kind () != TARGET_WAITKIND_NO_RESUMED) { /* Expedited registers. */ - if (!stop_reply->regcache.empty ()) + if (status->kind () != TARGET_WAITKIND_THREAD_EXITED + && !stop_reply->regcache.empty ()) { struct regcache *regcache = get_thread_arch_regcache (this, ptid, stop_reply->arch); @@ -8358,7 +8359,7 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status, again. Keep waiting for events. */ rs->waiting_for_stop_reply = 1; break; - case 'N': case 'T': case 'S': case 'X': case 'W': + case 'N': case 'T': case 'S': case 'X': case 'W': case 'w': { /* There is a stop reply to handle. */ rs->waiting_for_stop_reply = 0; diff --git a/gdbserver/server.cc b/gdbserver/server.cc index 07a3319d114..5099db1ee31 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -3061,6 +3061,7 @@ resume (struct thread_resume *actions, size_t num_actions) if (cs.last_status.kind () != TARGET_WAITKIND_EXITED && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED + && cs.last_status.kind () != TARGET_WAITKIND_THREAD_EXITED && cs.last_status.kind () != TARGET_WAITKIND_NO_RESUMED) current_thread->last_status = cs.last_status;