From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) by sourceware.org (Postfix) with ESMTPS id BBB47384144A for ; Mon, 20 Jun 2022 22:55:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BBB47384144A 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-f41.google.com with SMTP id n1so16260715wrg.12 for ; Mon, 20 Jun 2022 15:55:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cztqu2ss18lE+QO6QVGoqjOa/t9QZ3r8Pwd9k00wb7s=; b=jTdcV/V/xcfOqzNyo2zNFgGPGNLZJ7Z5HBx8EQhe80I8sL2c7VWYMflFyAiogeKwd+ PTNqHy/fPWe6DDRuOEqmGJdHlzCfr4R90+uqz3MXJbPnl5qSgtH5kZGCoR/L1GWZPWv/ 9eLidS25V+i+v/AkZbaQqKSwzBltLW+DE2YiN5NLlx54eN00LPpyBfNHVamKoe6VcA0P MBI3JCcFl5K0ofgp79bq6YV+R7X4Co+gFaKN1NtuVn4Xk1iRUeL3HnN4LlSkLD4IrI8J XLCPHm5ufOTDjQQDQAMkwigCbZT9m2SS8Xx4d1TgYko5+w4GPWPdPiq5MbtBfLlCgHQM MHag== X-Gm-Message-State: AJIora/pBLCdR2CKVrkeI9yR9FsRfv2nCaKIAIiO7whrpJ3y7d9JHJCx oFYjo9lVBAIwZhQMTjMUYIi3pZMtGw4= X-Google-Smtp-Source: AGRyM1uG3tBObuXUvXz5CVXUp0mqSpp+l7y+k+JHZe5AWXjlTUzKsm5uxXTfWNjG93yAPVxJp/79XA== X-Received: by 2002:a5d:4a42:0:b0:21b:838f:12bc with SMTP id v2-20020a5d4a42000000b0021b838f12bcmr15990137wrs.523.1655765709638; Mon, 20 Jun 2022 15:55:09 -0700 (PDT) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id t5-20020a05600001c500b0020d106c0386sm6092342wrx.89.2022.06.20.15.55.08 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 20 Jun 2022 15:55:08 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 22/25] Ignore failure to read PC when resuming Date: Mon, 20 Jun 2022 23:54:16 +0100 Message-Id: <20220620225419.382221-23-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220620225419.382221-1-pedro@palves.net> References: <20220620225419.382221-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.8 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, T_SCC_BODY_TEXT_LINE 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-List-Received-Date: Mon, 20 Jun 2022 22:55:12 -0000 If GDB sets a GDB_TO_EXIT option on a thread, and the thread exits, the server reports the corresponding thread exit event, and forgets about the thread, i.e., removes the exited thread from its thread list. On the GDB side, GDB set the GDB_TO_EXIT option on a thread, GDB delays deleting the thread from its thread list until it sees the corresponding thread exit event, as that event needs special handling in infrun. When a thread disappears from the target, but it still exists on GDB's thread list, in all-stop RSP mode, it can happen that GDB ends up trying to resume such an already-exited-thread that GDB doesn't yet know is gone. When that happens, against GDBserver, typically the ongoing execution command fails with this error: ... PC register is not available (gdb) At the remote protocol level, we may see e.g., this: [remote] Packet received: w0;p97479.978d2 [remote] wait: exit [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) = [infrun] print_target_wait_results: 619641.620754.0 [Thread 619641.620754], [infrun] print_target_wait_results: status->kind = THREAD_EXITED, exit_status = 0 [infrun] handle_inferior_event: status->kind = THREAD_EXITED, exit_status = 0 [infrun] context_switch: Switching context from 0.0.0 to 619641.620754.0 [infrun] clear_proceed_status_thread: 619641.620754.0 GDB saw an exit event for thread 619641.620754. After processing it, infrun decides to re-resume the target again. To do that, infrun picks some other thread that isn't exited yet from GDB's perspective, switches to it, and calls keep_going. Below, infrun happens to pick thread p97479.97479, the leader, which also exited, but GDB doesn't know yet: ... [remote] Sending packet: $Hgp97479.97479#75 [remote] Packet received: OK [remote] Sending packet: $g#67 [remote] Packet received: xxxxxxxxxxxxxxxxx (...snip...) [1120 bytes omitted] [infrun] reset: reason=handling event [infrun] maybe_set_commit_resumed_all_targets: not requesting commit-resumed for target remote, no resumed threads [infrun] fetch_inferior_event: exit PC register is not available (gdb) The Linux backends, both in GDB and in GDBserver, already silently ignore failures to resume, with the understanding that we'll see an exit event soon. Core of GDB doesn't do that yet, though. This patch is a small step in that direction. It swallows the error when thrown from within resume_1. There are likely are spots where we will need similar treatment, but we can tackle them as we find them. After this patch, we'll see something like this instead: [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [640478.640478.0] at 0x0 [infrun] do_target_resume: resume_ptid=640478.0.0, step=0, sig=GDB_SIGNAL_0 [remote] Sending packet: $vCont;c:p9c5de.-1#78 [infrun] prepare_to_wait: prepare_to_wait [infrun] reset: reason=handling event [infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target remote [infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target remote [infrun] fetch_inferior_event: exit [infrun] fetch_inferior_event: enter [infrun] scoped_disable_commit_resumed: reason=handling event [infrun] random_pending_event_thread: None found. [remote] wait: enter [remote] Packet received: W0;process:9c5de [remote] wait: exit [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) = [infrun] print_target_wait_results: 640478.0.0 [process 640478], [infrun] print_target_wait_results: status->kind = EXITED, exit_status = 0 [infrun] handle_inferior_event: status->kind = EXITED, exit_status = 0 [Inferior 1 (process 640478) exited normally] [infrun] stop_waiting: stop_waiting [infrun] reset: reason=handling event (gdb) [infrun] fetch_inferior_event: exit Change-Id: I7f1c7610923435c4e98e70acc5ebe5ebbac581e2 --- gdb/infrun.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 6c273fd8cf2..babdb94696e 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2513,7 +2513,28 @@ resume_1 (enum gdb_signal sig) step = false; } - CORE_ADDR pc = regcache_read_pc (regcache); + CORE_ADDR pc = 0; + try + { + pc = regcache_read_pc (regcache); + } + catch (const gdb_exception_error &err) + { + /* Swallow errors as it may be that the current thread exited + and we've haven't seen its exit status yet. Let the + resumption continue and we'll collect the exit event + shortly. */ + if (err.error == TARGET_CLOSE_ERROR) + throw; + + if (debug_infrun) + { + string_file buf; + exception_print (&buf, err); + infrun_debug_printf ("resume: swallowing error: %s", + buf.string ().c_str ()); + } + } infrun_debug_printf ("step=%d, signal=%s, trap_expected=%d, " "current thread [%s] at %s", -- 2.36.0