From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 246BA39BD42C for ; Wed, 9 Jun 2021 20:06:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 246BA39BD42C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wm1-x333.google.com with SMTP id h11-20020a05600c350bb02901b59c28e8b4so4604546wmq.1 for ; Wed, 09 Jun 2021 13:06:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WQwHcxaPciHjt3tCyIT6URAUMOCrlf15NB1SiqO4Oe8=; b=Fe18u9C45F4ZIS8aSXfC+OBJAKTUsDY5putJndiIGVuxeW2x6Mn0v8K4h7C+/DDnxT m6kGgmcUI4H2dq17uhvu4tFLIVxuszickXkqBjqHZojjWA908qb/Gsw2ay42Dskx58we Xn5pmz2/NhC9zDRgJaae9GsWVCVWGfUrDoY+cjTt1vkbDPBq/pn3kiQFPYVHGlinxjSM qZN3GXqh8WV2iZH/7pLi6UFgthIJOKl9u2OMCkMZO3vm11/oUkgK01gf64BLGvery/dC GwXBw4PGbzl7Vy32GiPMXJyf0sShhwilQa0gIigNmAdqw1zsndpWGfjVlV6MYSyWE8no h8Mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WQwHcxaPciHjt3tCyIT6URAUMOCrlf15NB1SiqO4Oe8=; b=CMSbPPxtlcXKyZbbZPblrEUK1ElIAI+llwrMnf5UOOOj6cQtM4Z/4wx53EODOS+Q+e f7tWjl8u8omGepibumtUGHi0qco+0VaKt2SVvRA6dhS68mOhVt57g7A2rKaDYUZiLCPi R7g2eaMmgsaqdN9hoiKMkztGWN3BdvTIIx+m8mFyXKZeNHIMAlpBPXu9z3NpulsU40wP qeTRetSkswfrONToLsbYELQkG46FwwpdDtZCf+pKljnJLUa/yMXt3VKD5QLAXbqS6XRg SiYn2Au5uhDUsFV4F28ZtogWChsYFPpx5lJKkpVP3AFwXpNNHa3QA0llgO2v/PS5JTjf Y7ww== X-Gm-Message-State: AOAM5327YZZWt5KZ1g2opLWXKEbvQd0kJzlCECs1Ob1/zLeBwjKCP1Ep kNHe39nbh0DGjx2+2RFDk5CE2KFjDXEksw== X-Google-Smtp-Source: ABdhPJxNVPXSiuGArHSgjT+sLcbio+CIuw4ceEDvTXDBZcvDSFzs0KMc057oV3kpzYAVVtGKjWydTQ== X-Received: by 2002:a1c:4c07:: with SMTP id z7mr11247287wmf.90.1623269185051; Wed, 09 Jun 2021 13:06:25 -0700 (PDT) Received: from localhost (host109-151-46-70.range109-151.btcentralplus.com. [109.151.46.70]) by smtp.gmail.com with ESMTPSA id f8sm728669wmg.43.2021.06.09.13.06.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Jun 2021 13:06:24 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Subject: [PATCH 4/4] gdb/remote: error if a stop arrives for a non-resumed thread Date: Wed, 9 Jun 2021 21:06:17 +0100 Message-Id: <3768e00eacad6fed0539fe30669483f4f56bc0ce.1623268999.git.andrew.burgess@embecosm.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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-List-Received-Date: Wed, 09 Jun 2021 20:06:29 -0000 When looking at bug gdb/26819 I spotted that due to the configuration of OpenOCD, OpenOCD was sending GDB a stop reply for a thread that GDB was not expecting to be executing. If GDB was doing a non-displaced step-over, and so, had only sent a single step request to one specific thread, GDB would, assert that the thread that stopped should be in the process of completing a step-over. This would result in this assertion: infrun.c:5672: internal-error: int finish_step_over(execution_control_state*): Assertion `ecs->event_thread->control.trap_expected' failed. This commit is an attempt to have GDB spot when the incoming stop packet from the target is invalid and throw an error before we hit the above assert. So, in this commit, when processing the stop in the remote_target code, if the stop is for a thread that is not resumed, throw an error. There's no test for this, as it requires that a target send back an invalid stop packet, one that includes the wrong thread-id, I don't currently have any good ideas for how I would trigger such a remote packet. When looking at the original example from the bug report (which uses the RISC-V spike simulator and OpenOCD), when the invalid packet arrives the GDB session now looks like this: (gdb) continue stop received from remote for thread that should not be executing (gdb) info threads Id Target Id Frame 1 Thread 1 (Name: riscv.cpu0, state: single-step) (running) * 2 Thread 2 (Name: riscv.cpu1, state: single-step) (running) Unfortunately, at this point the session is effectively dead as the threads are still in the running state, but GDB is in all-stop mode, so isn't really expecting to be in this state. Given that, should we get to this point, we know that the remote is not following the rules, I'm not hugely worried. Even if we could put GDB back into a usable state, we couldn't reasonable expect to continue working with the remote when we know it's broken. gdb/ChangeLog: PR gdb/26819 * remote.c (remote_target::process_stop_reply): Catch the case where a stop reply arrives for a thread that was not resumed. --- gdb/ChangeLog | 6 ++++++ gdb/remote.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/gdb/remote.c b/gdb/remote.c index 85ab16e894e..1bb6f0303a3 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -8057,6 +8057,27 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, remote_notice_new_inferior (ptid, false); remote_thread_info *remote_thr = get_remote_thread_info (this, ptid); + + /* Check that the thread that is reported stopped is one that was + previously running. This catches the case where a badly behaving + target reports a stop for a thread that GDB thinks should already + be stopped. + + In many cases, reporting a stop for a thread that GDB thinks is + already stopped, turns out to be harmless, however, there are + cases, (e.g. when single stepping), where reporting a stop against + an unexpected thread will trigger assertion failures from within + infrun. + + The one exception to this logic is when we stop after an exec + call. The exec will replace the main thread of the inferior, even + if the exec is performed in some other thread. Thus, GDB might + step thread 2, but the exec-stop is reported in thread 1. */ + if (remote_thr->get_resume_state () != resume_state::RESUMED + && status->kind != TARGET_WAITKIND_EXECD) + error (_("stop received from remote for thread that should " + "not be executing")); + remote_thr->core = stop_reply->core; remote_thr->stop_reason = stop_reply->stop_reason; remote_thr->watch_data_address = stop_reply->watch_data_address; -- 2.25.4