From patchwork Wed Nov 6 20:52:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 35705 Received: (qmail 3128 invoked by alias); 6 Nov 2019 20:52:43 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3112 invoked by uid 89); 6 Nov 2019 20:52:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-8.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH autolearn=ham version=3.3.1 spammy=waited X-HELO: esa6.hgst.iphmx.com Received: from esa6.hgst.iphmx.com (HELO esa6.hgst.iphmx.com) (216.71.154.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 06 Nov 2019 20:52:42 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1573073562; x=1604609562; h=date:from:to:cc:subject:in-reply-to:message-id: references:mime-version; bh=GFxUj75VCaqAjrMtEQfPXq06uasLfi5hx6k4Jcz3oB0=; b=jm2ipcH8+OW7Y/AYboIWCKzVMQu4LxFIW8PWTskFJKOGn0vSOTZaky3D er3KCRYNACJoHIj5DjCievLGFfAYDiyYdaJR0SqWhpIDvMBY8MeualmhL 9yum6PLFv6wWlsUtuwv7f8NiH9PA5dOWmvhwjZZx2t7zge/XBeU3Eh8jO yuWeDB88WOlN/3MM74TmhbgjOp0o/pT5LLKdL+I+jlhuVG6sBDdeG+b1k mmFAzSwSfkCoTxEYU+7/BaE90jIms94Vs8qc13OVu5Bs+9aKlKscwNmO8 Smx511Tducx9qtXU2mQjDikJ+T7HEcT8jnnYrqCsQY1Yn0gXXu8k2ikK3 w==; IronPort-SDR: 5esSp8aYnvUgwzONe4+ZNLzUbbdhSj96Bt18Epoi68R2Lpn4Diic3OU56q5KtZpkBJ19vTpZ/y iLiBgcuwOTFL8AmDsOK+OkQ+R2fVTuy8lJKtL8Yoojz0AvRdF5RDIHFEvZ1LS5+baA/c7cHPw6 x0jjsIqGFRN3vDVM6097ia0V1xVTTw4a0taDRCOGsjZizBxcn9zjtExgEX14VD2QbfMJgmLTnn jAFYeym8Pd9pZSBLoTN1rLLRU0beOWtuscRMkr2Rt88X6TM4JmKzqEjklRCyJ+1NWeu0CkbSXz YQk= Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 07 Nov 2019 04:52:41 +0800 IronPort-SDR: Lbd8V1GXrJx5h9J86EvtjQmPYclQhLGdyzi8lTMWG8HHY6DCXc9WmaYHFc/BoimybjB6A5tt3/ KPOo/H2nCx3AS+JbYpWShDqzrRQKmIy87FGAGVanE1p/aZsPQPCygbPMwR9tA/HsEtk8qW4loq ZbUxcS7bO6K+0SPrzQUqxoGH+kBQVBZT4h9CIxCEoALBPj1ki+/XnFgu2CeDTOAcxejHhUD/XF 9p0jso3MgJbbvAf7KZRj2PIUsoa5X/9pwFWC75DlrA+p+i1ypsDqW/hTCQmMGsEpgeBGspmVPm 29ZtcAmB3UdpgZjRwmuwybV5 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Nov 2019 12:47:52 -0800 IronPort-SDR: 7A6gxTatS10VQWD8JC8y15G66YQ+B1B2rmSdHIwDl9z1B7bf/CIzMT8P4s6+LX1rvBaZclzve8 bZe0vuysmwfoZXd2v5zhmNViy6yBTwJ9mHEmEut1phjRP119DuBLVYCVPBaIoKQFTxQ96lFRp6 OCBglvn5HvJnVu3gea9jkvuwo5ezmWU0cqqVpUKUiYmDZlwhKq7zojlCuVvzZ5bBN+jc29b2sA 5z/WItauUFKONHpG8w4B8ioyHG4DD2B3s5RrkNu2Hz8S1YD98G1B6Gl3UUmRdHDpFm+VhlOWtZ fhg= WDCIronportException: Internal Received: from unknown (HELO redsun52) ([10.149.66.28]) by uls-op-cesaip01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Nov 2019 12:52:39 -0800 Date: Wed, 6 Nov 2019 20:52:37 +0000 (GMT) From: "Maciej W. Rozycki" To: Pedro Alves , gdb-patches@sourceware.org cc: Jim Wilson Subject: [PATCH v2 4/4] Unregister the inferior from the event loop if failed to resume In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (LFD 202 2017-01-01) MIME-Version: 1.0 Fix an issue with GDB starting to effectively busy-loop (though still accepting and interpreting commands) using the full processing power available when a remote stub has gone closing the connection while GDB is waiting for user input once the inferior has failed to resume. This was observed with a `riscv64-linux-gnu' cross-GDB and RISC-V/Linux `gdbserver' being developed and an attempt to step over the `ret' aka `c.jr ra' instruction where the value held in the `ra' aka `x1' register and therefore the address of a software-stepping breakpoint to insert is 0. Here's a record of a remote debug session leading to the issue: Sending packet: $vCont?#49...Packet received: vCont;c;C;t Packet vCont (verbose-resume) is supported Sending packet: $vCont;c:p6857.-1#b8...infrun: infrun_async(1) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [process -1], infrun: status->kind = ignore infrun: handle_inferior_event status->kind = ignore infrun: prepare_to_wait Packet received: T05swbreak:;02:f0f8ffff3f000000;20:b807565515000000;thread:p6857.6857;core:1; infrun: target_wait (-1.0.0, status) = infrun: 26711.26711.0 [Thread 26711.26711], infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: stop_pc = 0x15555607b8 Sending packet: $qXfer:libraries-svr4:read::0,1000#20...Packet received: l infrun: BPSTAT_WHAT_SINGLE infrun: thread [Thread 26711.26711] still needs step-over infrun: skipping breakpoint: stepping past insn at: 0x15555607b8 Sending packet: $X15555607b8,2:\202\200#2e...Packet received: OK infrun: skipping breakpoint: stepping past insn at: 0x15555607b8 infrun: skipping breakpoint: stepping past insn at: 0x15555607b8 infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=1, current thread [Thread 26711.26711] at 0x15555607b8 Sending packet: $m15555607b8,2#07...Packet received: 8280 Sending packet: $m15555607b8,2#07...Packet received: 8280 Sending packet: $g#67...Packet received: 00000000000000000000000000000000f0f8ffff3f000000d0c1b9aa2a00000020f76d55150000000f00000000000000ec6e555515000000ffffff6f00000000f0faffff3f00000090f0565515000000000000000000000052e57464000000000500000000000000887801000000000028f1565515000000010000000000000008f8ffff3f000000722f6c696236342f60f156551500000000000000000000000000000000000000000000000000000008f75655150000000100000000000000f5feffefffffffff80de56551500000050f9ffff3f00000068f9ffff3f000000ae585655150000000b00000000000000fffdff6f00000000fcffffffffffffff[552 bytes omitted] Sending packet: $m0,40#2d...Packet received: E01 Sending packet: $m0,1#fa...Packet received: E01 Sending packet: $m0,40#2d...Packet received: E01 Sending packet: $m0,1#fa...Packet received: E01 infrun: skipping breakpoint: stepping past insn at: 0x15555607b8 infrun: clear_step_over_info Cannot access memory at address 0x0 (gdb) At this point a command was issued to kill `gdbserver' and GDB responded immediately by entering the event loop: infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [process -1], infrun: status->kind = no-resumed infrun: handle_inferior_event status->kind = no-resumed infrun: TARGET_WAITKIND_NO_RESUMED (ignoring: bg) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [process -1], infrun: status->kind = no-resumed infrun: handle_inferior_event status->kind = no-resumed infrun: TARGET_WAITKIND_NO_RESUMED (ignoring: bg) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [process -1], infrun: status->kind = no-resumed infrun: handle_inferior_event status->kind = no-resumed infrun: TARGET_WAITKIND_NO_RESUMED (ignoring: bg) infrun: prepare_to_wait [...] This is because `remote_target::resume' enables the asynchronous event loop, as indicated by the first `infrun: infrun_async(1)' record above, and then the EOF condition on the remote connection is delivered as an event, but there are no resumed children to be waited for and no other event waiting that would stop the loop. Correct that then by disabling the asynchronous event as execution completion would, where applicable, i.e. in the all-stop mode. This makes the final sequence of the session look like: Sending packet: $m0,40#2d...Packet received: E01 Sending packet: $m0,1#fa...Packet received: E01 Sending packet: $m0,40#2d...Packet received: E01 Sending packet: $m0,1#fa...Packet received: E01 infrun: infrun_async(0) infrun: skipping breakpoint: stepping past insn at: 0x15555607b8 infrun: clear_step_over_info Cannot access memory at address 0x0 (gdb) and GDB does not trigger the loop at this point if `gdbserver' goes away as the asynchronous event loop has already been disabled. gdb/ * infrun.c (resume): In the `catch' clause also unregister the inferior from the event loop. --- Hi, It might be that the non-stop mode requires additional clean-up here, however I have no way to work with that at the moment, so I'll be leaving any investigation to someone who has and will be inclined to look into it. Maciej New change in v2. --- gdb/infrun.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) gdb-resume-async.diff Index: binutils-gdb/gdb/infrun.c =================================================================== --- binutils-gdb.orig/gdb/infrun.c +++ binutils-gdb/gdb/infrun.c @@ -2614,11 +2614,17 @@ resume (gdb_signal sig) } catch (const gdb_exception &ex) { - /* If resuming is being aborted for any reason, delete any - single-step breakpoint resume_1 may have created, to avoid - confusing the following resumption, and to avoid leaving - single-step breakpoints perturbing other threads, in case - we're running in non-stop mode. */ + /* If resuming is being aborted for any reason, and we are in + the all-stop mode, then unregister the inferior from the event + loop. This is done so that when the inferior is not running + we don't get distracted by spurious inferior output. */ + if (!non_stop && target_has_execution && target_can_async_p ()) + target_async (0); + + /* Also delete any single-step breakpoint resume_1 may have + created, to avoid confusing the following resumption, and to + avoid leaving single-step breakpoints perturbing other threads, + in case we're running in non-stop mode. */ if (inferior_ptid != null_ptid) { thread_info *tp = inferior_thread ();