changeset 22230:0bbc8be90207 v8.2.1664

patch 8.2.1664: memory leak when using :mkview with a terminal buffer Commit: https://github.com/vim/vim/commit/c2c820563441499892359da949db3c8f7f16d109 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Sep 11 22:10:22 2020 +0200 patch 8.2.1664: memory leak when using :mkview with a terminal buffer Problem: Memory leak when using :mkview with a terminal buffer. Solution: Don't use a hastab for :mkview. (Rob Pilling, closes https://github.com/vim/vim/issues/6935)
author Bram Moolenaar <Bram@vim.org>
date Fri, 11 Sep 2020 22:15:03 +0200
parents 9bad0d1cde0e
children e1311fb42cd4
files src/session.c src/terminal.c src/testdir/test_mksession.vim src/version.c
diffstat 4 files changed, 40 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/session.c
+++ b/src/session.c
@@ -303,14 +303,12 @@ put_view_curpos(FILE *fd, win_T *wp, cha
 put_view(
     FILE	*fd,
     win_T	*wp,
-    int		add_edit,	// add ":edit" command to view
-    unsigned	*flagp,		// vop_flags or ssop_flags
-    int		current_arg_idx	// current argument index of the window, use
-				// -1 if unknown
-#ifdef FEAT_TERMINAL
-    , hashtab_T *terminal_bufs
-#endif
-    )
+    int		add_edit,	     // add ":edit" command to view
+    unsigned	*flagp,		     // vop_flags or ssop_flags
+    int		current_arg_idx,     // current argument index of the window,
+				     // use -1 if unknown
+    hashtab_T *terminal_bufs UNUSED) // already encountered terminal buffers,
+				     // can be NULL
 {
     win_T	*save_curwin;
     int		f;
@@ -825,9 +823,11 @@ makeopens(
 	{
 	    if (!ses_do_win(wp))
 		continue;
-	    if (put_view(fd, wp, wp != edited_win, &ssop_flags, cur_arg_idx
+	    if (put_view(fd, wp, wp != edited_win, &ssop_flags, cur_arg_idx,
 #ifdef FEAT_TERMINAL
-							 , &terminal_bufs
+							 &terminal_bufs
+#else
+							 NULL
 #endif
 		 ) == FAIL)
 		goto fail;
@@ -1102,11 +1102,6 @@ ex_mkrc(exarg_T	*eap)
     char_u	*viewFile = NULL;
     unsigned	*flagp;
 #endif
-#ifdef FEAT_TERMINAL
-    hashtab_T	terminal_bufs;
-
-    hash_init(&terminal_bufs);
-#endif
 
     if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview)
     {
@@ -1263,11 +1258,8 @@ ex_mkrc(exarg_T	*eap)
 	    }
 	    else
 	    {
-		failed |= (put_view(fd, curwin, !using_vdir, flagp, -1
-#ifdef FEAT_TERMINAL
-							       , &terminal_bufs
-#endif
-			    ) == FAIL);
+		failed |= (put_view(fd, curwin, !using_vdir, flagp, -1, NULL)
+								      == FAIL);
 	    }
 	    if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save")
 								      == FAIL)
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -940,7 +940,7 @@ term_write_session(FILE *fd, win_T *wp, 
     const int	bufnr = wp->w_buffer->b_fnum;
     term_T	*term = wp->w_buffer->b_term;
 
-    if (wp->w_buffer->b_nwindows > 1)
+    if (terminal_bufs != NULL && wp->w_buffer->b_nwindows > 1)
     {
 	// There are multiple views into this terminal buffer. We don't want to
 	// create the terminal multiple times. If it's the first time, create,
@@ -978,7 +978,7 @@ term_write_session(FILE *fd, win_T *wp, 
     if (fprintf(fd, "let s:term_buf_%d = bufnr()", bufnr) < 0)
 	return FAIL;
 
-    if (wp->w_buffer->b_nwindows > 1)
+    if (terminal_bufs != NULL && wp->w_buffer->b_nwindows > 1)
     {
 	char *hash_key = alloc(NUMBUFLEN);
 
--- a/src/testdir/test_mksession.vim
+++ b/src/testdir/test_mksession.vim
@@ -351,9 +351,8 @@ func Test_mksession_blank_windows()
   call delete('Xtest_mks.out')
 endfunc
 
-if has('terminal')
-
 func Test_mksession_terminal_shell()
+  CheckFeature terminal
   CheckFeature quickfix
 
   terminal
@@ -374,6 +373,8 @@ func Test_mksession_terminal_shell()
 endfunc
 
 func Test_mksession_terminal_no_restore_cmdarg()
+  CheckFeature terminal
+
   terminal ++norestore
   mksession! Xtest_mks.out
   let lines = readfile('Xtest_mks.out')
@@ -389,6 +390,8 @@ func Test_mksession_terminal_no_restore_
 endfunc
 
 func Test_mksession_terminal_no_restore_funcarg()
+  CheckFeature terminal
+
   call term_start(&shell, {'norestore': 1})
   mksession! Xtest_mks.out
   let lines = readfile('Xtest_mks.out')
@@ -404,6 +407,8 @@ func Test_mksession_terminal_no_restore_
 endfunc
 
 func Test_mksession_terminal_no_restore_func()
+  CheckFeature terminal
+
   terminal
   call term_setrestore(bufnr('%'), 'NONE')
   mksession! Xtest_mks.out
@@ -420,6 +425,8 @@ func Test_mksession_terminal_no_restore_
 endfunc
 
 func Test_mksession_terminal_no_ssop()
+  CheckFeature terminal
+
   terminal
   set sessionoptions-=terminal
   mksession! Xtest_mks.out
@@ -437,6 +444,7 @@ func Test_mksession_terminal_no_ssop()
 endfunc
 
 func Test_mksession_terminal_restore_other()
+  CheckFeature terminal
   CheckFeature quickfix
 
   terminal
@@ -456,6 +464,8 @@ func Test_mksession_terminal_restore_oth
 endfunc
 
 func Test_mksession_terminal_shared_windows()
+  CheckFeature terminal
+
   terminal
   let term_buf = bufnr()
   new
@@ -481,7 +491,18 @@ func Test_mksession_terminal_shared_wind
   call delete('Xtest_mks.out')
 endfunc
 
-endif " has('terminal')
+func Test_mkview_terminal_windows()
+  CheckFeature terminal
+
+  " create two window on the same terminal to check this is handled OK
+  terminal
+  let term_buf = bufnr()
+  exe 'sbuf ' .. term_buf
+  mkview! Xtestview
+
+  call StopShellInTerminal(term_buf)
+  call delete('Xtestview')
+endfunc
 
 " Test :mkview with a file argument.
 func Test_mkview_file()
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1664,
+/**/
     1663,
 /**/
     1662,