From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Stephen Leake Newsgroups: gmane.emacs.bugs Subject: bug#37620: 26.1; ada-mode 6.2.1 partial parsing occasionally hangs while moving point Date: Tue, 03 Mar 2020 14:29:14 -0800 Message-ID: <86r1y9jcn9.fsf@stephe-leake.org> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="129377"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (windows-nt) To: 37620@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Mar 03 23:30:15 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j9G3L-000XXt-9n for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 03 Mar 2020 23:30:15 +0100 Original-Received: from localhost ([::1]:54700 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9G3J-000055-Sd for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 03 Mar 2020 17:30:13 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:55053) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9G3A-0008WV-8V for bug-gnu-emacs@gnu.org; Tue, 03 Mar 2020 17:30:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9G38-0003kH-Mr for bug-gnu-emacs@gnu.org; Tue, 03 Mar 2020 17:30:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:34146) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j9G38-0003iM-9y for bug-gnu-emacs@gnu.org; Tue, 03 Mar 2020 17:30:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1j9G38-0003DV-5m; Tue, 03 Mar 2020 17:30:02 -0500 X-Loop: help-debbugs@gnu.org In-Reply-To: Resent-From: Stephen Leake Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, stephen_leake@stephe-leake.org Resent-Date: Tue, 03 Mar 2020 22:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37620 X-GNU-PR-Package: emacs, ada-mode Original-Received: via spool by 37620-submit@debbugs.gnu.org id=B37620.158327456212296 (code B ref 37620); Tue, 03 Mar 2020 22:30:02 +0000 Original-Received: (at 37620) by debbugs.gnu.org; 3 Mar 2020 22:29:22 +0000 Original-Received: from localhost ([127.0.0.1]:40118 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j9G2T-0003CG-Lt for submit@debbugs.gnu.org; Tue, 03 Mar 2020 17:29:22 -0500 Original-Received: from gateway32.websitewelcome.com ([192.185.145.123]:22765) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1j9G2Q-0003C6-BW for 37620@debbugs.gnu.org; Tue, 03 Mar 2020 17:29:19 -0500 Original-Received: from cm12.websitewelcome.com (cm12.websitewelcome.com [100.42.49.8]) by gateway32.websitewelcome.com (Postfix) with ESMTP id A7E6A63BC0 for <37620@debbugs.gnu.org>; Tue, 3 Mar 2020 16:29:17 -0600 (CST) Original-Received: from host2007.hostmonster.com ([67.20.76.71]) by cmsmtp with SMTP id 9G2PjBBGRvBMd9G2Pj5oaV; Tue, 03 Mar 2020 16:29:17 -0600 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=stephe-leake.org; s=default; h=Content-Type:MIME-Version:Message-ID:Date: Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=wMXxOR7r9s5shclg28slSC4x6kp8l2kGy3LLVXvhfLU=; b=FBRe3U6QQn47bxXAmCQKBtQNQ/ HYVzkPTbxA5hVNlnH4Jzt0/58TRxZJJmhtPFx4/O/t6OTVfdYMC1MmM3qj8z6bPsbMEvsTP8U13Qu Py1EkiYopXD+bXDV9RQYlYld7uBBcAIT6mjx+LC3uhOrmyAMkkyiCwCEcKveFLJJgjmhhfwWewwgI 9oTUMvD73K3Ildi6uXa/ZkSdbzkZe5elXd502d1Chdt8ImqvqlrL7VlHHLjjIA8pF3UBheflAgGrd sQOGq5ZDzX3oR/4TaR13ChEICSEITnJVqOdSV+EbWVFI28rmC6ZjeyWGq6lqzPS8SE0LH8LQSfVrk 6RbQD4kg==; Original-Received: from [76.77.182.20] (port=65436 helo=Takver4) by host2007.hostmonster.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from ) id 1j9G2P-000pBt-1w for 37620@debbugs.gnu.org; Tue, 03 Mar 2020 15:29:17 -0700 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - host2007.hostmonster.com X-AntiAbuse: Original Domain - debbugs.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - stephe-leake.org X-BWhitelist: no X-Source-IP: 76.77.182.20 X-Source-L: No X-Exim-ID: 1j9G2P-000pBt-1w X-Source-Sender: (Takver4) [76.77.182.20]:65436 X-Source-Auth: stephen_leake@stephe-leake.org X-Email-Count: 1 X-Source-Cap: c3RlcGhlbGU7c3RlcGhlbGU7aG9zdDIwMDcuaG9zdG1vbnN0ZXIuY29t X-Local-Domain: yes X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:176817 Archived-At: --=-=-= Content-Type: text/plain There is a bug in error recovery that can cause the parser to hang; that may be the cause of this bug. Patch attached. -- -- Stephe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=patch.diff --- a/wisitoken-parse-lr-mckenzie_recover-base.adb +++ b/wisitoken-parse-lr-mckenzie_recover-base.adb @@ -2,7 +2,7 @@ -- -- Base utilities for McKenzie_Recover -- --- Copyright (C) 2018, 2019 Free Software Foundation, Inc. +-- Copyright (C) 2018 - 2020 Free Software Foundation, Inc. -- -- This library is free software; you can redistribute it and/or modify it -- under terms of the GNU General Public License as published by the Free @@ -30,49 +30,56 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Base is return Boolean is Done_Count : SAL.Base_Peek_Type := 0; + Skip : Boolean; begin -- Return True if all parsers are done, or if any parser has a config -- available to check. for P_Status of Parser_Status loop + Skip := False; + case P_Status.Recover_State is when Active | Ready => if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then if P_Status.Parser_State.Recover.Check_Count - Check_Delta_Limit >= Min_Success_Check_Count then -- fail; another parser succeeded, this one taking too long. Done_Count := Done_Count + 1; + Skip := True; elsif Total_Enqueue_Count + P_Status.Parser_State.Recover.Config_Full_Count >= Enqueue_Limit then -- fail Done_Count := Done_Count + 1; + Skip := True; end if; end if; - case P_Status.Recover_State is - when Active => - if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then - -- Still working - return True; - else - if P_Status.Active_Workers = 0 then - -- fail; no configs left to check. - Done_Count := Done_Count + 1; + if not Skip then + case P_Status.Recover_State is + when Active => + if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then + -- Still working + return True; + else + if P_Status.Active_Workers = 0 then + -- fail; no configs left to check. + Done_Count := Done_Count + 1; + end if; end if; - end if; - when Ready => - if P_Status.Parser_State.Recover.Config_Heap.Count > 0 and then - P_Status.Parser_State.Recover.Config_Heap.Min_Key <= P_Status.Parser_State.Recover.Results.Min_Key - then - -- Still more to check. - return True; + when Ready => + if P_Status.Parser_State.Recover.Config_Heap.Count > 0 and then + P_Status.Parser_State.Recover.Config_Heap.Min_Key <= P_Status.Parser_State.Recover.Results.Min_Key + then + -- Still more to check. + return True; - elsif P_Status.Active_Workers = 0 then - Done_Count := Done_Count + 1; - end if; + elsif P_Status.Active_Workers = 0 then + Done_Count := Done_Count + 1; + end if; - when others => - null; - end case; + when others => + null; + end case; + end if; when Success | Fail => Done_Count := Done_Count + 1; @@ -135,6 +142,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Base is (Parsers, Parser_Status, Min_Success_Check_Count, Total_Enqueue_Count, Check_Delta_Limit, Enqueue_Limit) is Done_Count : SAL.Base_Peek_Type := 0; + Skip : Boolean; Min_Cost : Integer := Integer'Last; Min_Cost_Index : SAL.Base_Peek_Type; @@ -168,6 +176,8 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Base is -- No task_id in outline trace messages, because they may appear in -- .parse_good for I in Parser_Status'Range loop + Skip := False; + declare P_Status : Base.Parser_Status renames Parser_Status (I); begin @@ -186,6 +196,7 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Base is P_Status.Fail_Mode := Fail_Check_Delta; Done_Count := Done_Count + 1; + Skip := True; elsif Total_Enqueue_Count + P_Status.Parser_State.Recover.Config_Full_Count >= Enqueue_Limit then if Trace_McKenzie > Outline then @@ -200,48 +211,51 @@ package body WisiToken.Parse.LR.McKenzie_Recover.Base is P_Status.Fail_Mode := Fail_Enqueue_Limit; Done_Count := Done_Count + 1; + Skip := True; end if; end if; - case P_Status.Recover_State is - when Active => - if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then - if P_Status.Parser_State.Recover.Config_Heap.Min_Key < Min_Cost then - Min_Cost := P_Status.Parser_State.Recover.Config_Heap.Min_Key; - Min_Cost_Index := I; - -- not done - end if; - else - if P_Status.Active_Workers = 0 then - -- No configs left to check (rarely happens with real languages). - if Trace_McKenzie > Outline then - Put_Line - (Trace.all, P_Status.Parser_State.Label, "fail; no configs left", Task_ID => False); + if not Skip then + case P_Status.Recover_State is + when Active => + if P_Status.Parser_State.Recover.Config_Heap.Count > 0 then + if P_Status.Parser_State.Recover.Config_Heap.Min_Key < Min_Cost then + Min_Cost := P_Status.Parser_State.Recover.Config_Heap.Min_Key; + Min_Cost_Index := I; + -- not done + end if; + else + if P_Status.Active_Workers = 0 then + -- No configs left to check (rarely happens with real languages). + if Trace_McKenzie > Outline then + Put_Line + (Trace.all, P_Status.Parser_State.Label, "fail; no configs left", Task_ID => False); + end if; + P_Status.Recover_State := Fail; + P_Status.Fail_Mode := Fail_No_Configs_Left; + + Done_Count := Done_Count + 1; end if; - P_Status.Recover_State := Fail; - P_Status.Fail_Mode := Fail_No_Configs_Left; - - Done_Count := Done_Count + 1; end if; - end if; - when Ready => - if P_Status.Parser_State.Recover.Config_Heap.Count > 0 and then - P_Status.Parser_State.Recover.Config_Heap.Min_Key <= - P_Status.Parser_State.Recover.Results.Min_Key - then - -- Still more to check. We don't check Min_Cost here so this parser - -- can finish quickly. - Set_Outputs (I); - return; - - elsif P_Status.Active_Workers = 0 then - P_Status.Recover_State := Success; - Done_Count := Done_Count + 1; - end if; - when others => - null; - end case; + when Ready => + if P_Status.Parser_State.Recover.Config_Heap.Count > 0 and then + P_Status.Parser_State.Recover.Config_Heap.Min_Key <= + P_Status.Parser_State.Recover.Results.Min_Key + then + -- Still more to check. We don't check Min_Cost here so this parser + -- can finish quickly. + Set_Outputs (I); + return; + + elsif P_Status.Active_Workers = 0 then + P_Status.Recover_State := Success; + Done_Count := Done_Count + 1; + end if; + when others => + null; + end case; + end if; when Success | Fail => Done_Count := Done_Count + 1; --=-=-=--