]> granicus.if.org Git - vim/commitdiff
patch 8.2.1948: GUI: crash when handling message while closing a window v8.2.1948
authorBram Moolenaar <Bram@vim.org>
Wed, 4 Nov 2020 10:03:12 +0000 (11:03 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 4 Nov 2020 10:03:12 +0000 (11:03 +0100)
Problem:    GUI: crash when handling message while closing a window. (Srinath
            Avadhanula)
Solution:   Don't handle message while closing a window. (closes #7250)

src/getchar.c
src/globals.h
src/version.c
src/window.c

index 6e469f49b53eb016c941c6e2819ca436ac1f184f..b0cc8c2317d27d28f6dfb976c91aa9e1234689d5 100644 (file)
@@ -2155,7 +2155,8 @@ parse_queued_messages(void)
 
     // Do not handle messages while redrawing, because it may cause buffers to
     // change or be wiped while they are being redrawn.
-    if (updating_screen)
+    // Also bail out when parsing messages was explicitly disabled.
+    if (updating_screen || dont_parse_messages)
        return;
 
     // If memory allocation fails during startup we'll exit but curbuf or
index 379a532fac03663c7601372a2066fd4aeb8a0b95..dd7fa4a53179f14b6d9a11ef701eb4c81b9a05c4 100644 (file)
@@ -581,6 +581,12 @@ EXTERN int diff_need_scrollbind INIT(= FALSE);
 // ('lines' and 'rows') must not be changed.
 EXTERN int     updating_screen INIT(= FALSE);
 
+#ifdef MESSAGE_QUEUE
+// While closing windows or buffers messages should not be handled to avoid
+// using invalid windows or buffers.
+EXTERN int     dont_parse_messages INIT(= FALSE);
+#endif
+
 #ifdef FEAT_MENU
 // The root of the menu hierarchy.
 EXTERN vimmenu_T       *root_menu INIT(= NULL);
index 015cf4cb17ab7c6545c4a5409a4a9ec72231ef59..d380452c40ec0177492621a26bb8dddacc25eeb1 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1948,
 /**/
     1947,
 /**/
index 9dbfae210d49f6b708a9942032aed1da8ce626a0..2cd06630fff6a1fef6abc42e6d1ef15bb0e2a364 100644 (file)
@@ -2569,7 +2569,12 @@ win_close(win_T *win, int free_buf)
 
     // Now we are really going to close the window.  Disallow any autocommand
     // to split a window to avoid trouble.
+    // Also bail out of parse_queued_messages() to avoid it tries to update the
+    // screen.
     ++split_disallowed;
+#ifdef MESSAGE_QUEUE
+    ++dont_parse_messages;
+#endif
 
     // Free the memory used for the window and get the window that received
     // the screen space.
@@ -2626,6 +2631,9 @@ win_close(win_T *win, int free_buf)
     }
 
     --split_disallowed;
+#ifdef MESSAGE_QUEUE
+    --dont_parse_messages;
+#endif
 
     /*
      * If last window has a status line now and we don't want one,