On Sa, 26 Mai 2012, Christian Brabandt wrote: > On Fr, 25 Mai 2012, Alex Efros wrote: > > Thanks! But, sorry, I just found another simple way to crash 7.3.530 > > without tabs: > > > > $ vi -u /dev/null --noplugin > > :autocmd BufWinLeave * if empty(getbufvar(0+expand('<abuf>'), '&bt')) | > > lclose | endif > > :lexpr system('echo :1:some') > > :lopen > > :wincmd p > > :bd > > Vim: Caught deadly signal SEGV > > Segmentation fault > > I'll look into it.
Here is another patch. I made win_close() return a status, whether it failed or not. But although win_close() is called in many places, I made it only in 1 place at do_buffer() evaluate the return value of win_close(), to not introduce too many other changes. regards, Christian -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php
diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -1151,7 +1151,10 @@ */ while (buf == curbuf && (firstwin != lastwin || first_tabpage->tp_next != NULL)) - win_close(curwin, FALSE); + { + if (win_close(curwin, FALSE) == FAIL); + return FAIL; + } #endif /* diff --git a/src/proto/window.pro b/src/proto/window.pro --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -9,7 +9,7 @@ void win_equal __ARGS((win_T *next_curwin, int current, int dir)); void close_windows __ARGS((buf_T *buf, int keep_curwin)); int one_window __ARGS((void)); -void win_close __ARGS((win_T *win, int free_buf)); +int win_close __ARGS((win_T *win, int free_buf)); void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp)); void win_free_all __ARGS((void)); win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp)); diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -2147,7 +2147,7 @@ * * Called by :quit, :close, :xit, :wq and findtag(). */ - void + int win_close(win, free_buf) win_T *win; int free_buf; @@ -2164,19 +2164,19 @@ if (last_window()) { EMSG(_("E444: Cannot close last window")); - return; + return FAIL; } #ifdef FEAT_AUTOCMD if (win == aucmd_win) { EMSG(_("E813: Cannot close autocmd window")); - return; + return FAIL; } if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) { EMSG(_("E814: Cannot close window, only autocmd window would remain")); - return; + return FAIL; } #endif @@ -2184,7 +2184,7 @@ * and then close the window and the tab page to avoid that curwin and * curtab are invalid while we are freeing memory. */ if (close_last_window_tabpage(win, free_buf, prev_curtab)) - return; + return OK; /* When closing the help window, try restoring a snapshot after closing * the window. Otherwise clear the snapshot, it's now invalid. */ @@ -2210,15 +2210,15 @@ other_buffer = TRUE; apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win) || last_window()) - return; + return FAIL; } apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win) || last_window()) - return; + return FAIL; # ifdef FEAT_EVAL /* autocmds may abort script processing */ if (aborting()) - return; + return FAIL; # endif } #endif @@ -2246,7 +2246,7 @@ * other window or moved to another tab page. */ if (!win_valid(win) || last_window() || curtab != prev_curtab || close_last_window_tabpage(win, free_buf, prev_curtab)) - return; + return FAIL; /* Free the memory used for the window and get the window that received * the screen space. */ @@ -2326,6 +2326,7 @@ #endif redraw_all_later(NOT_VALID); + return OK; } /*