# HG changeset patch # User Bram Moolenaar # Date 1599855303 -7200 # Node ID 0bbc8be902075ce526f1efd7cbbb0ad63f2a75b7 # Parent 9bad0d1cde0e44b911f790b8eda1edfc3194eedf patch 8.2.1664: memory leak when using :mkview with a terminal buffer Commit: https://github.com/vim/vim/commit/c2c820563441499892359da949db3c8f7f16d109 Author: Bram Moolenaar 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) diff --git a/src/session.c b/src/session.c --- 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) diff --git a/src/terminal.c b/src/terminal.c --- 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); diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim --- 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() diff --git a/src/version.c b/src/version.c --- 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,