From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) by sourceware.org (Postfix) with ESMTPS id 8E996380EBC2 for ; Wed, 13 Jul 2022 22:25:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8E996380EBC2 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-f45.google.com with SMTP id r14so53406wrg.1 for ; Wed, 13 Jul 2022 15:25:27 -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=pu3n89bpvbtbOc6k0rtvm2aXuSDLObVLI7MvKmJi2Nc=; b=Q+RJ3RN52saFwLWGnUDxuWGDwwb5EJlhQu61DZEsBZN1x9qbGg960tAlffr9lZqfLh 4XhHWiCEV1AGPn0AjwwKk0M7sLglnb6VPksR06JqqssCD3Cj1OIewfmQXpIAW4bRu8yY i91idQlWx0JHGT+awlUc5UpHGjd4NpILrVoGvUCj5hzFE/NxcjyCIXHN9eM4ANxBz+Ma 4xrYclSsgz3rpsVrYMLsM29i2ZOtQZahjj+vGJ9yPgQhC/HUXY4swntKAoUrCm+A6jD8 2xxn1Leb9QcreMjxdPB+V60mPdyR7DCkooFlxDYMSm38YouJPtgmdftRuJVt9GQnwu+f BVMQ== X-Gm-Message-State: AJIora+YPOW/5d9lNTnEokztoi8nSi7dZEy09FgNICej0vPicC47Xfqu RFGwK1kg34OB8lZaYHrIHKqxfFSIFLM= X-Google-Smtp-Source: AGRyM1vDxnb5xYnluNlpWaoN4b2BQSXed7OHBLFH7u55mgv11TSMZp6rEG0WllZYp9Oprn2LwYVlcQ== X-Received: by 2002:a5d:61d0:0:b0:21d:5e08:af3c with SMTP id q16-20020a5d61d0000000b0021d5e08af3cmr5198973wrv.25.1657751126394; Wed, 13 Jul 2022 15:25:26 -0700 (PDT) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id n31-20020a05600c501f00b003a2c7bf0497sm3504356wmr.16.2022.07.13.15.25.25 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 13 Jul 2022 15:25:25 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH v2 23/29] Ignore failure to read PC when resuming Date: Wed, 13 Jul 2022 23:24:27 +0100 Message-Id: <20220713222433.374898-24-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220713222433.374898-1-pedro@palves.net> References: <20220713222433.374898-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.9 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: Wed, 13 Jul 2022 22:25:29 -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 6df70e374b4..e565c9b0e33 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2525,7 +2525,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