]> granicus.if.org Git - vim/commitdiff
patch 9.0.0967: leaking memory from autocmd windows v9.0.0967
authorBram Moolenaar <Bram@vim.org>
Mon, 28 Nov 2022 20:34:52 +0000 (20:34 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 28 Nov 2022 20:34:52 +0000 (20:34 +0000)
Problem:    Leaking memory from autocmd windows.
Solution:   Free window when auc_win is not NULL.

src/autocmd.c
src/eval.c
src/globals.h
src/quickfix.c
src/screen.c
src/version.c
src/window.c

index 3a081281333c9fbac987a7e55c71655c866b7fa2..aca990cb51f1619be23487ad39317099517b2c6b 100644 (file)
@@ -653,12 +653,7 @@ free_all_autocmds(void)
     }
     ga_clear(&augroups);
 
-    for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
-       if (aucmd_win[i].auc_win_used)
-       {
-           aucmd_win[i].auc_win_used = FALSE;
-           win_remove(aucmd_win[i].auc_win, NULL);
-       }
+    // aucmd_win[] is freed in win_free_all()
 }
 #endif
 
@@ -1553,12 +1548,11 @@ aucmd_prepbuf(
        for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; ++auc_idx)
            if (!aucmd_win[auc_idx].auc_win_used)
            {
-               auc_win = win_alloc_popup_win();
+               if (aucmd_win[auc_idx].auc_win == NULL)
+                   aucmd_win[auc_idx].auc_win = win_alloc_popup_win();
+               auc_win = aucmd_win[auc_idx].auc_win;
                if (auc_win != NULL)
-               {
-                   aucmd_win[auc_idx].auc_win = auc_win;
                    aucmd_win[auc_idx].auc_win_used = TRUE;
-               }
                break;
            }
 
@@ -1667,6 +1661,9 @@ win_found:
        // Remove the window and frame from the tree of frames.
        (void)winframe_remove(curwin, &dummy, NULL);
        win_remove(curwin, NULL);
+
+       // The window is marked as not used, but it is not freed, it can be
+       // used again.
        aucmd_win[aco->use_aucmd_win_idx].auc_win_used = FALSE;
        last_status(FALSE);         // may need to remove last status line
 
index c43158a29a32abfacdb1fd8078ed5c2cfaf03b17..20883d430960c0f75471d112a7ccb59f5d26a9fc 100644 (file)
@@ -5084,8 +5084,9 @@ garbage_collect(int testing)
     FOR_ALL_TAB_WINDOWS(tp, wp)
        abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
                                                                  NULL, NULL);
+    // window-local variables in autocmd windows
     for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
-       if (aucmd_win[i].auc_win_used)
+       if (aucmd_win[i].auc_win != NULL)
            abort = abort || set_ref_in_item(
                    &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
 #ifdef FEAT_PROP_POPUP
index eadff43c990a809fe3efbbfdd90a041cf72d4264..e69856801e9ddd06974e110b627cba3a9567e5c3 100644 (file)
@@ -984,8 +984,9 @@ EXTERN win_T        *curwin;        // currently active window
 #define AUCMD_WIN_COUNT 5
 
 typedef struct {
-  win_T        *auc_win;       // window used in aucmd_prepbuf()
-  int  auc_win_used;   // this auc_win is being used
+  win_T        *auc_win;       // Window used in aucmd_prepbuf().  When not NULL the
+                       // window has been allocated.
+  int  auc_win_used;   // This auc_win is being used.
 } aucmdwin_T;
 
 EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT];
index e8716d26809a0b1040429279d352584c20dfb4e2..4c414e0ad90a2949f54a2b34a974dd3e11308e5d 100644 (file)
@@ -6639,10 +6639,10 @@ load_dummy_buffer(
 
            // restore curwin/curbuf and a few other things
            aucmd_restbuf(&aco);
-       }
 
-       if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe))
-           wipe_buffer(newbuf_to_wipe.br_buf, FALSE);
+           if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe))
+               wipe_buffer(newbuf_to_wipe.br_buf, FALSE);
+       }
 
        // Add back the "dummy" flag, otherwise buflist_findname_stat() won't
        // skip it.
index 3bf15d6c85161a6a8f2ca093591a4ce95dd04ebe..c5c6a7ac97970f5dd80b5cf45296a8534b2b2434 100644 (file)
@@ -2439,7 +2439,7 @@ retry:
     FOR_ALL_TAB_WINDOWS(tp, wp)
        win_free_lsize(wp);
     for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
-       if (aucmd_win[i].auc_win_used)
+       if (aucmd_win[i].auc_win != NULL)
            win_free_lsize(aucmd_win[i].auc_win);
 #ifdef FEAT_PROP_POPUP
     // global popup windows
@@ -2484,7 +2484,7 @@ retry:
        }
     }
     for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
-       if (aucmd_win[i].auc_win_used
+       if (aucmd_win[i].auc_win != NULL
                && aucmd_win[i].auc_win->w_lines == NULL
                && win_alloc_lines(aucmd_win[i].auc_win) == FAIL)
        {
index 240def4532fc31d270d4adac13613b648941d550..395bb2ad734268cfaaa3ca89905c37ecdca0ecdf 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    967,
 /**/
     966,
 /**/
index 24f25d65b78f3fbd272335221701b13129bd2479..9a49cad8d1ab890ffbf859041f43fa457508de1b 100644 (file)
@@ -3293,10 +3293,10 @@ win_free_all(void)
        tabpage_close(TRUE);
 
     for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
-       if (aucmd_win[i].auc_win_used)
+       if (aucmd_win[i].auc_win != NULL)
        {
            (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL);
-           aucmd_win[i].auc_win_used = FALSE;
+           aucmd_win[i].auc_win = NULL;
        }
 
     while (firstwin != NULL)