From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#33547: 27.0.50; Emacs stuck in infinite loop in garbage collection Date: Fri, 30 Nov 2018 16:33:16 -0800 Organization: UCLA Computer Science Department Message-ID: References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------BDFC05A0562DC36BEEA5FF7A" X-Trace: blaine.gmane.org 1543624338 24037 195.159.176.226 (1 Dec 2018 00:32:18 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 1 Dec 2018 00:32:18 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 Cc: 33547-done@debbugs.gnu.org To: Philipp Stephani Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Dec 01 01:32:13 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gStCe-00060K-5S for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Dec 2018 01:32:12 +0100 Original-Received: from localhost ([::1]:35266 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gStEf-0005sZ-Cu for geb-bug-gnu-emacs@m.gmane.org; Fri, 30 Nov 2018 19:34:17 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36866) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gStEW-0005sG-JD for bug-gnu-emacs@gnu.org; Fri, 30 Nov 2018 19:34:10 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gStEQ-0000Yq-Sq for bug-gnu-emacs@gnu.org; Fri, 30 Nov 2018 19:34:07 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:52449) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gStEQ-0000YT-Hc for bug-gnu-emacs@gnu.org; Fri, 30 Nov 2018 19:34:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gStEQ-0005Cl-Cz for bug-gnu-emacs@gnu.org; Fri, 30 Nov 2018 19:34:02 -0500 In-Reply-To: Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-To: bug-gnu-emacs@gnu.org Resent-Date: Sat, 01 Dec 2018 00:34:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: cc-closed 33547 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Mail-Followup-To: 33547@debbugs.gnu.org, eggert@cs.ucla.edu, p.stephani2@gmail.com Original-Received: via spool by 33547-done@debbugs.gnu.org id=D33547.154362440819955 (code D ref 33547); Sat, 01 Dec 2018 00:34:02 +0000 Original-Received: (at 33547-done) by debbugs.gnu.org; 1 Dec 2018 00:33:28 +0000 Original-Received: from localhost ([127.0.0.1]:56705 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gStDp-0005Bj-LB for submit@debbugs.gnu.org; Fri, 30 Nov 2018 19:33:28 -0500 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:42898) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gStDn-0005BT-Oa for 33547-done@debbugs.gnu.org; Fri, 30 Nov 2018 19:33:24 -0500 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 3ADFD16050D; Fri, 30 Nov 2018 16:33:18 -0800 (PST) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id Unb_me36NhYM; Fri, 30 Nov 2018 16:33:16 -0800 (PST) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id AA62916051A; Fri, 30 Nov 2018 16:33:16 -0800 (PST) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id fxSuEVJeNkfy; Fri, 30 Nov 2018 16:33:16 -0800 (PST) Original-Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 8840216022D; Fri, 30 Nov 2018 16:33:16 -0800 (PST) Openpgp: preference=signencrypt Autocrypt: addr=eggert@cs.ucla.edu; prefer-encrypt=mutual; keydata= xsFNBEyAcmQBEADAAyH2xoTu7ppG5D3a8FMZEon74dCvc4+q1XA2J2tBy2pwaTqfhpxxdGA9 Jj50UJ3PD4bSUEgN8tLZ0san47l5XTAFLi2456ciSl5m8sKaHlGdt9XmAAtmXqeZVIYX/UFS 96fDzf4xhEmm/y7LbYEPQdUdxu47xA5KhTYp5bltF3WYDz1Ygd7gx07Auwp7iw7eNvnoDTAl KAl8KYDZzbDNCQGEbpY3efZIvPdeI+FWQN4W+kghy+P6au6PrIIhYraeua7XDdb2LS1en3Ss mE3QjqfRqI/A2ue8JMwsvXe/WK38Ezs6x74iTaqI3AFH6ilAhDqpMnd/msSESNFt76DiO1ZK QMr9amVPknjfPmJISqdhgB1DlEdw34sROf6V8mZw0xfqT6PKE46LcFefzs0kbg4GORf8vjG2 Sf1tk5eU8MBiyN/bZ03bKNjNYMpODDQQwuP84kYLkX2wBxxMAhBxwbDVZudzxDZJ1C2VXujC OJVxq2kljBM9ETYuUGqd75AW2LXrLw6+MuIsHFAYAgRr7+KcwDgBAfwhPBYX34nSSiHlmLC+ KaHLeCLF5ZI2vKm3HEeCTtlOg7xZEONgwzL+fdKo+D6SoC8RRxJKs8a3sVfI4t6CnrQzvJbB n6gxdgCu5i29J1QCYrCYvql2UyFPAK+do99/1jOXT4m2836j1wARAQABzSBQYXVsIEVnZ2Vy dCA8ZWdnZXJ0QGNzLnVjbGEuZWR1PsLBfgQTAQIAKAUCTIByZAIbAwUJEswDAAYLCQgHAwIG FQgCCQoLBBYCAwECH Content-Language: en-US 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: 208.118.235.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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:152944 Archived-At: This is a multi-part message in MIME format. --------------BDFC05A0562DC36BEEA5FF7A Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Thanks for reporting that. I installed the first attached patch into Emacs master and am marking this bug as done. I am not sure whether a simpler patch should be installed into the emacs-26 branch, but the second attached patch should do the trick for that if needed, not that it's easy to test this sort of thing. --------------BDFC05A0562DC36BEEA5FF7A Content-Type: text/x-patch; name="0001-Fix-infloop-in-GC-mark_kboards-master.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Fix-infloop-in-GC-mark_kboards-master.patch" >From 7d9fa89fb3f6db0bdc3960bbbf6c0cf34c98d1ca Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 30 Nov 2018 14:22:54 -0800 Subject: [PATCH] Fix infloop in GC mark_kboards * src/keyboard.c (KBD_BUFFER_SIZE): Now a constant, not a macro. (kbd_fetch_ptr, kbd_store_ptr): These now always point somewhere into kbd_buffer, instead of sometimes pointing just past the end which led to serious bugs (Bug#33547). All uses changed. (kbd_store_ptr): No longer volatile. This variable has not been accessed by a signal handler for some time, it seems. (next_kbd_event, prev_kbd_event): New functions. (kbd_buffer_nr_stored, process_special_events): Simplify. --- src/keyboard.c | 181 ++++++++++++++++++++----------------------------- 1 file changed, 72 insertions(+), 109 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index be727a6549..59acb2dd08 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -92,7 +92,7 @@ volatile int interrupt_input_blocked; The maybe_quit function checks this. */ volatile bool pending_signals; -#define KBD_BUFFER_SIZE 4096 +enum { KBD_BUFFER_SIZE = 4096 }; KBOARD *initial_kboard; KBOARD *current_kboard; @@ -286,15 +286,11 @@ static bool input_was_pending; static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; /* Pointer to next available character in kbd_buffer. - If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. - This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the - next available char is in kbd_buffer[0]. */ + If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. */ static union buffered_input_event *kbd_fetch_ptr; -/* Pointer to next place to store character in kbd_buffer. This - may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next - character should go in kbd_buffer[0]. */ -static union buffered_input_event *volatile kbd_store_ptr; +/* Pointer to next place to store character in kbd_buffer. */ +static union buffered_input_event *kbd_store_ptr; /* The above pair of variables forms a "queue empty" flag. When we enqueue a non-hook event, we increment kbd_store_ptr. When we @@ -302,8 +298,7 @@ static union buffered_input_event *volatile kbd_store_ptr; there is input available if the two pointers are not equal. Why not just have a flag set and cleared by the enqueuing and - dequeuing functions? Such a flag could be screwed up by interrupts - at inopportune times. */ + dequeuing functions? The code is a bit simpler this way. */ static void recursive_edit_unwind (Lisp_Object buffer); static Lisp_Object command_loop (void); @@ -375,6 +370,20 @@ static void deliver_user_signal (int); static char *find_user_signal_name (int); static void store_user_signal_events (void); +/* Advance or retreat a buffered input event pointer. */ + +static union buffered_input_event * +next_kbd_event (union buffered_input_event *ptr) +{ + return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1; +} + +static union buffered_input_event * +prev_kbd_event (union buffered_input_event *ptr) +{ + return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1; +} + /* Like EVENT_START, but assume EVENT is an event. This pacifies gcc -Wnull-dereference, which might otherwise complain about earlier checks that EVENT is indeed an event. */ @@ -3338,8 +3347,6 @@ readable_events (int flags) do { - if (event == kbd_buffer + KBD_BUFFER_SIZE) - event = kbd_buffer; if (!( #ifdef USE_TOOLKIT_SCROLL_BARS (flags & READABLE_EVENTS_FILTER_EVENTS) && @@ -3356,7 +3363,7 @@ readable_events (int flags) && !((flags & READABLE_EVENTS_FILTER_EVENTS) && event->kind == BUFFER_SWITCH_EVENT)) return 1; - event++; + event = next_kbd_event (event); } while (event != kbd_store_ptr); } @@ -3410,12 +3417,8 @@ event_to_kboard (struct input_event *event) static int kbd_buffer_nr_stored (void) { - return kbd_fetch_ptr == kbd_store_ptr - ? 0 - : (kbd_fetch_ptr < kbd_store_ptr - ? kbd_store_ptr - kbd_fetch_ptr - : ((kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr - + (kbd_store_ptr - kbd_buffer))); + int n = kbd_store_ptr - kbd_fetch_ptr; + return n + (n < 0 ? KBD_BUFFER_SIZE : 0); } #endif /* Store an event obtained at interrupt level into kbd_buffer, fifo */ @@ -3466,12 +3469,10 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window), make_fixnum (c))); kb->kbd_queue_has_data = true; - union buffered_input_event *sp; - for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) - { - if (sp == kbd_buffer + KBD_BUFFER_SIZE) - sp = kbd_buffer; + for (union buffered_input_event *sp = kbd_fetch_ptr; + sp != kbd_store_ptr; sp = next_kbd_event (sp)) + { if (event_to_kboard (&sp->ie) == kb) { sp->ie.kind = NO_EVENT; @@ -3516,22 +3517,18 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, Just ignore the second one. */ else if (event->kind == BUFFER_SWITCH_EVENT && kbd_fetch_ptr != kbd_store_ptr - && ((kbd_store_ptr == kbd_buffer - ? kbd_buffer + KBD_BUFFER_SIZE - 1 - : kbd_store_ptr - 1)->kind) == BUFFER_SWITCH_EVENT) + && prev_kbd_event (kbd_store_ptr)->kind == BUFFER_SWITCH_EVENT) return; - if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE) - kbd_store_ptr = kbd_buffer; - /* Don't let the very last slot in the buffer become full, since that would make the two pointers equal, and that is indistinguishable from an empty buffer. Discard the event if it would fill the last slot. */ - if (kbd_fetch_ptr - 1 != kbd_store_ptr) + union buffered_input_event *next_slot = next_kbd_event (kbd_store_ptr); + if (kbd_fetch_ptr != next_slot) { *kbd_store_ptr = *event; - ++kbd_store_ptr; + kbd_store_ptr = next_slot; #ifdef subprocesses if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2 && ! kbd_on_hold_p ()) @@ -3574,11 +3571,8 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, void kbd_buffer_unget_event (struct selection_input_event *event) { - if (kbd_fetch_ptr == kbd_buffer) - kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE; - /* Don't let the very last slot in the buffer become full, */ - union buffered_input_event *kp = kbd_fetch_ptr - 1; + union buffered_input_event *kp = prev_kbd_event (kbd_fetch_ptr); if (kp != kbd_store_ptr) { kp->sie = *event; @@ -3666,12 +3660,9 @@ kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help) void discard_mouse_events (void) { - union buffered_input_event *sp; - for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) + for (union buffered_input_event *sp = kbd_fetch_ptr; + sp != kbd_store_ptr; sp = next_kbd_event (sp)) { - if (sp == kbd_buffer + KBD_BUFFER_SIZE) - sp = kbd_buffer; - if (sp->kind == MOUSE_CLICK_EVENT || sp->kind == WHEEL_EVENT || sp->kind == HORIZ_WHEEL_EVENT @@ -3696,18 +3687,13 @@ discard_mouse_events (void) bool kbd_buffer_events_waiting (void) { - union buffered_input_event *sp; - - for (sp = kbd_fetch_ptr; - sp != kbd_store_ptr && sp->kind == NO_EVENT; - ++sp) - { - if (sp == kbd_buffer + KBD_BUFFER_SIZE) - sp = kbd_buffer; - } - - kbd_fetch_ptr = sp; - return sp != kbd_store_ptr && sp->kind != NO_EVENT; + for (union buffered_input_event *sp = kbd_fetch_ptr; + ; sp = next_kbd_event (sp)) + if (sp == kbd_store_ptr || sp->kind != NO_EVENT) + { + kbd_fetch_ptr = sp; + return sp != kbd_store_ptr && sp->kind != NO_EVENT; + } } @@ -3836,11 +3822,7 @@ kbd_buffer_get_event (KBOARD **kbp, mouse movement enabled and available. */ if (kbd_fetch_ptr != kbd_store_ptr) { - union buffered_input_event *event; - - event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) - ? kbd_fetch_ptr - : kbd_buffer); + union buffered_input_event *event = kbd_fetch_ptr; *kbp = event_to_kboard (&event->ie); if (*kbp == 0) @@ -3861,7 +3843,7 @@ kbd_buffer_get_event (KBOARD **kbp, since otherwise swallow_events will see it and process it again. */ struct selection_input_event copy = event->sie; - kbd_fetch_ptr = event + 1; + kbd_fetch_ptr = next_kbd_event (event); input_pending = readable_events (0); x_handle_selection_event (©); #else @@ -3876,7 +3858,7 @@ kbd_buffer_get_event (KBOARD **kbp, || defined (HAVE_NS) || defined (USE_GTK) case MENU_BAR_ACTIVATE_EVENT: { - kbd_fetch_ptr = event + 1; + kbd_fetch_ptr = next_kbd_event (event); input_pending = readable_events (0); if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window))) x_activate_menubar (XFRAME (event->ie.frame_or_window)); @@ -3921,7 +3903,7 @@ kbd_buffer_get_event (KBOARD **kbp, case SELECT_WINDOW_EVENT: { obj = make_lispy_event (&event->ie); - kbd_fetch_ptr = event + 1; + kbd_fetch_ptr = next_kbd_event (event); } break; default: @@ -3975,7 +3957,7 @@ kbd_buffer_get_event (KBOARD **kbp, /* Wipe out this event, to catch bugs. */ clear_event (&event->ie); - kbd_fetch_ptr = event + 1; + kbd_fetch_ptr = next_kbd_event (event); } } } @@ -4042,17 +4024,9 @@ kbd_buffer_get_event (KBOARD **kbp, static void process_special_events (void) { - union buffered_input_event *event; - - for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event) + for (union buffered_input_event *event = kbd_fetch_ptr; + event != kbd_store_ptr; event = next_kbd_event (event)) { - if (event == kbd_buffer + KBD_BUFFER_SIZE) - { - event = kbd_buffer; - if (event == kbd_store_ptr) - break; - } - /* If we find a stored X selection request, handle it now. */ if (event->kind == SELECTION_REQUEST_EVENT || event->kind == SELECTION_CLEAR_EVENT) @@ -4066,28 +4040,21 @@ process_special_events (void) cyclically. */ struct selection_input_event copy = event->sie; - union buffered_input_event *beg - = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) - ? kbd_buffer : kbd_fetch_ptr; + int moved_events; - if (event > beg) - memmove (beg + 1, beg, (event - beg) * sizeof *beg); - else if (event < beg) + if (event < kbd_fetch_ptr) { - if (event > kbd_buffer) - memmove (kbd_buffer + 1, kbd_buffer, - (event - kbd_buffer) * sizeof *kbd_buffer); - *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1); - if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1) - memmove (beg + 1, beg, - (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) * sizeof *beg); + memmove (kbd_buffer + 1, kbd_buffer, + (event - kbd_buffer) * sizeof *kbd_buffer); + kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1]; + moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr; } - - if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr = kbd_buffer + 1; else - kbd_fetch_ptr++; + moved_events = event - kbd_fetch_ptr; + memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr, + moved_events * sizeof *kbd_fetch_ptr); + kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr); input_pending = readable_events (0); x_handle_selection_event (©); #else @@ -10261,11 +10228,10 @@ stuff_buffered_input (Lisp_Object stuffstring) rms: we should stuff everything back into the kboard it came from. */ - for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++) + for (; kbd_fetch_ptr != kbd_store_ptr; + kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr)) { - if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr = kbd_buffer; if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT) stuff_char (kbd_fetch_ptr->ie.code); @@ -12003,21 +11969,18 @@ mark_kboards (void) mark_object (KVAR (kb, echo_string)); mark_object (KVAR (kb, echo_prompt)); } - { - union buffered_input_event *event; - for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) - { - if (event == kbd_buffer + KBD_BUFFER_SIZE) - event = kbd_buffer; - /* These two special event types has no Lisp_Objects to mark. */ - if (event->kind != SELECTION_REQUEST_EVENT - && event->kind != SELECTION_CLEAR_EVENT) - { - mark_object (event->ie.x); - mark_object (event->ie.y); - mark_object (event->ie.frame_or_window); - mark_object (event->ie.arg); - } - } - } + + for (union buffered_input_event *event = kbd_fetch_ptr; + event != kbd_store_ptr; event = next_kbd_event (event)) + { + /* These two special event types have no Lisp_Objects to mark. */ + if (event->kind != SELECTION_REQUEST_EVENT + && event->kind != SELECTION_CLEAR_EVENT) + { + mark_object (event->ie.x); + mark_object (event->ie.y); + mark_object (event->ie.frame_or_window); + mark_object (event->ie.arg); + } + } } -- 2.19.2 --------------BDFC05A0562DC36BEEA5FF7A Content-Type: text/x-patch; name="0001-Fix-infloop-in-GC-mark_kboards-emacs-26.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Fix-infloop-in-GC-mark_kboards-emacs-26.patch" >From 7df217da0c97702988aadb6b231067a8bcda1703 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 30 Nov 2018 14:14:18 -0800 Subject: [PATCH] Fix infloop in GC mark_kboards Do not merge to master, as I have a more systematic fix there. * src/keyboard.c (mark_kboards): Fix infloop (Bug#33547). --- src/keyboard.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/keyboard.c b/src/keyboard.c index 0d56ea3f7a..dccc6b7f12 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12011,7 +12011,12 @@ mark_kboards (void) for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) { if (event == kbd_buffer + KBD_BUFFER_SIZE) - event = kbd_buffer; + { + event = kbd_buffer; + if (event == kbd_store_ptr) + break; + } + /* These two special event types has no Lisp_Objects to mark. */ if (event->kind != SELECTION_REQUEST_EVENT && event->kind != SELECTION_CLEAR_EVENT) -- 2.19.2 --------------BDFC05A0562DC36BEEA5FF7A--