Don't execute some autocommands when v:dying is 2 or more.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index c1cbab8..a23032c 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -401,6 +401,8 @@
 				buffer being unloaded "<afile>".
 				Don't change to another buffer, it will cause
 				problems.
+				When exiting and v:dying is 2 or more this
+				event is not triggered.
 							*BufWinEnter*
 BufWinEnter			After a buffer is displayed in a window.  This
 				can be when the buffer is loaded (after
@@ -422,6 +424,8 @@
 				NOTE: When this autocommand is executed, the
 				current buffer "%" may be different from the
 				buffer being unloaded "<afile>".
+				When exiting and v:dying is 2 or more this
+				event is not triggered.
 							*BufWipeout*
 BufWipeout			Before completely deleting a buffer.  The
 				BufUnload and BufDelete events may be called
@@ -799,6 +803,8 @@
 				.viminfo file.  Executed only once, like
 				VimLeavePre.
 				To detect an abnormal exit use |v:dying|.
+				When v:dying is 2 or more this event is not
+				triggered.
 							*VimLeavePre*
 VimLeavePre			Before exiting Vim, just before writing the
 				.viminfo file.  This is executed only once,
@@ -807,6 +813,8 @@
 				Mostly useful with a "*" pattern. >
 	:autocmd VimLeavePre * call CleanupStuff()
 <				To detect an abnormal exit use |v:dying|.
+				When v:dying is 2 or more this event is not
+				triggered.
 							*VimResized*
 VimResized			After the Vim window was resized, thus 'lines'
 				and/or 'columns' changed.  Not when starting
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 2a2d601..08b79bb 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1348,7 +1348,9 @@
 		terminate normally. {only works on Unix}
 		Example: >
 	:au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif
-<
+<		Note: if another deadly signal is caught when v:dying is one,
+		VimLeave autocommands will not be executed.
+
 					*v:errmsg* *errmsg-variable*
 v:errmsg	Last given error message.  It's allowed to set this variable.
 		Example: >
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index e0a6159..30fb99d 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -30,9 +30,6 @@
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-When Vim crashes it may run out of stack while executing autocommands.  Patch
-to not run autocommands when leaving Vim? (James Vega, 2010 May 23)
-
 Patch for invalid mem access in completion. (Dominique Pelle, 2010 May 26)
 
 Invalid memory access when deleting funcref variable.  Patch by Lech Lorens,
diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt
index d59b622..f469ac0 100644
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -7166,6 +7166,10 @@
 after recovery is compared to the original file contents.  When they differ
 the buffer is marked as modified.
 
+When Vim is exiting because of a deadly signal, when v:dying is 2 or more,
+VimLeavePre, VimLeave, BufWinLeave and BufUnload autocommands are not
+executed.
+
 
 Added							*added-7.3*
 -----
diff --git a/src/main.c b/src/main.c
index ec7675e..f4e1fde 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1276,40 +1276,44 @@
 #endif
 
 #ifdef FEAT_AUTOCMD
-    /* Trigger BufWinLeave for all windows, but only once per buffer. */
-# if defined FEAT_WINDOWS
-    for (tp = first_tabpage; tp != NULL; tp = next_tp)
+    if (get_vim_var_nr(VV_DYING) <= 1)
     {
-	next_tp = tp->tp_next;
-	for (wp = (tp == curtab)
-		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+	/* Trigger BufWinLeave for all windows, but only once per buffer. */
+# if defined FEAT_WINDOWS
+	for (tp = first_tabpage; tp != NULL; tp = next_tp)
 	{
-	    buf = wp->w_buffer;
-	    if (buf->b_changedtick != -1)
+	    next_tp = tp->tp_next;
+	    for (wp = (tp == curtab)
+		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
 	    {
-		apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
-								  FALSE, buf);
-		buf->b_changedtick = -1;    /* note that we did it already */
-		/* start all over, autocommands may mess up the lists */
-		next_tp = first_tabpage;
-		break;
+		buf = wp->w_buffer;
+		if (buf->b_changedtick != -1)
+		{
+		    apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
+						    buf->b_fname, FALSE, buf);
+		    buf->b_changedtick = -1;    /* note that we did it already */
+		    /* start all over, autocommands may mess up the lists */
+		    next_tp = first_tabpage;
+		    break;
+		}
 	    }
 	}
-    }
 # else
-    apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname, FALSE, curbuf);
+	apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname,
+							       FALSE, curbuf);
 # endif
 
-    /* Trigger BufUnload for buffers that are loaded */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
-	if (buf->b_ml.ml_mfp != NULL)
-	{
-	    apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
+	/* Trigger BufUnload for buffers that are loaded */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    if (buf->b_ml.ml_mfp != NULL)
+	    {
+		apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
 								  FALSE, buf);
-	    if (!buf_valid(buf))	/* autocmd may delete the buffer */
-		break;
-	}
-    apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+		if (!buf_valid(buf))	/* autocmd may delete the buffer */
+		    break;
+	    }
+	apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+    }
 #endif
 
 #ifdef FEAT_VIMINFO
@@ -1319,7 +1323,8 @@
 #endif
 
 #ifdef FEAT_AUTOCMD
-    apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
+    if (get_vim_var_nr(VV_DYING) <= 1)
+	apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
 #endif
 
 #ifdef FEAT_PROFILE