Hi Alex!

On Do, 24 Mai 2012, Alex Efros wrote:

> I've discover this bug when trying to ':wq' in file with syntax errors using
> syntastic plugin with
>     let g:syntastic_auto_loc_list=1
> Instead of exiting from vim no matter there are syntax errors I got either
>     E855: Autocommands caused command to abort
> or vim segfault.
> 
> 
> To reproduce this bug it's enough to:
> 
>     $ vi -u /dev/null --noplugin
>     :autocmd BufWinLeave * if empty(&bt) | lclose | endif
>     :lexpr system('echo :1:some')
>     :lopen
>     :wincmd p
>     :q
>     (location list closes; got message E855: Autocommands caused command to
>     abort; vim doesn't exit)
>     :q
>     (now vim exit)

I have noticed something similar in my NrrwRgn plugin.
I am not sure, this is a bug, because at the time you issue :q the 
location list ist still open and in case another window is open, :q does 
not exit Vim.

> Or, with tabs and segfault:
> 
>     $ vi -u /dev/null --noplugin
>     :autocmd BufWinLeave * if empty(&bt) | lclose | endif
>     :tabnew
>     :lexpr system('echo :1:some')
>     :lopen
>     :wincmd p
>     :q
>     Vim: Caught deadly signal SEGV
>     Vim: Finished.
>     Segmentation fault
> 
> This happens on 7.3.515. Versions before 7.3.449 behave differently
> without tabs, but with tabs they all crash.

Attached patch fixes this issue.

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/proto/window.pro b/src/proto/window.pro
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -9,6 +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));
+int close_last_window_tabpage __ARGS((win_T *win, int free_buf, tabpage_T *prev_curtab));
 void 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));
diff --git a/src/window.c b/src/window.c
--- a/src/window.c
+++ b/src/window.c
@@ -2104,6 +2104,38 @@
 #endif
 }
 
+int
+close_last_window_tabpage(win, free_buf, prev_curtab)
+    win_T	*win;
+    int		free_buf;
+    tabpage_T   *prev_curtab;
+{
+    /*
+     * When closing the last window in a tab page first go to another tab
+     * page and then close the window and the tab page.  This avoids that
+     * curwin and curtab are not invalid while we are freeing memory, they may
+     * be used in GUI events.
+     */
+    if (firstwin == lastwin)
+    {
+	goto_tabpage_tp(alt_tabpage());
+	redraw_tabline = TRUE;
+
+	/* Safety check: Autocommands may have closed the window when jumping
+	 * to the other tab page. */
+	if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
+	{
+	    int	    h = tabline_height();
+
+	    win_close_othertab(win, free_buf, prev_curtab);
+	    if (h != tabline_height())
+		shell_new_rows();
+	}
+	return TRUE;
+    }
+    return FALSE;
+}
+
 /*
  * Close window "win".  Only works for the current tab page.
  * If "free_buf" is TRUE related buffer may be unloaded.
@@ -2146,26 +2178,11 @@
     /*
      * When closing the last window in a tab page first go to another tab
      * page and then close the window and the tab page.  This avoids that
-     * curwin and curtab are not invalid while we are freeing memory, they may
+     * curwin and curtab are invalid while we are freeing memory, they may
      * be used in GUI events.
      */
-    if (firstwin == lastwin)
-    {
-	goto_tabpage_tp(alt_tabpage());
-	redraw_tabline = TRUE;
-
-	/* Safety check: Autocommands may have closed the window when jumping
-	 * to the other tab page. */
-	if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
-	{
-	    int	    h = tabline_height();
-
-	    win_close_othertab(win, free_buf, prev_curtab);
-	    if (h != tabline_height())
-		shell_new_rows();
-	}
-	return;
-    }
+    if (close_last_window_tabpage(win, free_buf, prev_curtab))
+      return;
 
     /* When closing the help window, try restoring a snapshot after closing
      * the window.  Otherwise clear the snapshot, it's now invalid. */
@@ -2225,7 +2242,8 @@
 
     /* Autocommands may have closed the window already, or closed the only
      * other window or moved to another tab page. */
-    if (!win_valid(win) || last_window() || curtab != prev_curtab)
+    if (!win_valid(win) || last_window() || curtab != prev_curtab
+	    || close_last_window_tabpage(win, free_buf, prev_curtab))
 	return;
 
     /* Free the memory used for the window and get the window that received
@@ -2310,7 +2328,7 @@
 
 /*
  * Close window "win" in tab page "tp", which is not the current tab page.
- * This may be the last window ih that tab page and result in closing the tab,
+ * This may be the last window in that tab page and result in closing the tab,
  * thus "tp" may become invalid!
  * Caller must check if buffer is hidden and whether the tabline needs to be
  * updated.

Raspunde prin e-mail lui