aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2023-01-22 15:07:55 +0200
committerEli Zaretskii2023-01-22 15:09:21 +0200
commit8e83604dfe01e0ea56569c1bc129ecbc67583447 (patch)
tree3dab806ad5ea0adc8fbb6709281c76486318464a
parent808e101fabec64a2f7a42dd9d9207ebd402ead4f (diff)
downloademacs-8e83604dfe01e0ea56569c1bc129ecbc67583447.tar.gz
emacs-8e83604dfe01e0ea56569c1bc129ecbc67583447.zip
Avoid crashes in batch Emacs sub-processes on MS-Windows
* src/w32.c (shutdown_handler): When run in a separate thread, don't call functions that only the main (a.k.a. "Lisp") thread can call; instead, arrange for maybe_quit to kill Emacs. * src/w32fns.c (emacs_abort): Don't show GUI Abort dialogs in non-interactive sessions. (Bug#60556)
-rw-r--r--src/w32.c44
-rw-r--r--src/w32fns.c28
2 files changed, 47 insertions, 25 deletions
diff --git a/src/w32.c b/src/w32.c
index 47d79abc5b0..213fee15699 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10509,10 +10509,13 @@ init_ntproc (int dumping)
10509 } 10509 }
10510} 10510}
10511 10511
10512/* 10512/* shutdown_handler ensures that buffers' autosave files are up to
10513 shutdown_handler ensures that buffers' autosave files are 10513 date when the user logs off, or the system shuts down. It also
10514 up to date when the user logs off, or the system shuts down. 10514 shuts down Emacs when we get killed by another Emacs process, in
10515*/ 10515 which case we get the CTRL_CLOSE_EVENT. */
10516
10517extern DWORD dwMainThreadId;
10518
10516static BOOL WINAPI 10519static BOOL WINAPI
10517shutdown_handler (DWORD type) 10520shutdown_handler (DWORD type)
10518{ 10521{
@@ -10521,15 +10524,30 @@ shutdown_handler (DWORD type)
10521 || type == CTRL_LOGOFF_EVENT /* User logs off. */ 10524 || type == CTRL_LOGOFF_EVENT /* User logs off. */
10522 || type == CTRL_SHUTDOWN_EVENT) /* User shutsdown. */ 10525 || type == CTRL_SHUTDOWN_EVENT) /* User shutsdown. */
10523 { 10526 {
10524 /* If we are being shut down in noninteractive mode, we don't 10527 if (GetCurrentThreadId () == dwMainThreadId)
10525 care about the message stack, so clear it to avoid abort in 10528 {
10526 shut_down_emacs. This happens when an noninteractive Emacs 10529 /* If we are being shut down in noninteractive mode, we don't
10527 is invoked as a subprocess of Emacs, and the parent wants to 10530 care about the message stack, so clear it to avoid abort in
10528 kill us, e.g. because it's about to exit. */ 10531 shut_down_emacs. This happens when an noninteractive Emacs
10529 if (noninteractive) 10532 is invoked as a subprocess of Emacs, and the parent wants to
10530 clear_message_stack (); 10533 kill us, e.g. because it's about to exit. */
10531 /* Shut down cleanly, making sure autosave files are up to date. */ 10534 if (noninteractive)
10532 shut_down_emacs (0, Qnil); 10535 clear_message_stack ();
10536 /* Shut down cleanly, making sure autosave files are up to date. */
10537 shut_down_emacs (0, Qnil);
10538 }
10539 {
10540 /* This handler is run in a thread different from the main
10541 thread. (This is the normal situation when we are killed
10542 by Emacs, for example, which sends us the WM_CLOSE
10543 message). We cannot possibly call functions like
10544 shut_down_emacs or clear_message_stack in that case, since
10545 the main (a.k.a. "Lisp") thread could be in the middle of
10546 some Lisp program. So instead we arrange for maybe_quit to
10547 kill Emacs. */
10548 Vquit_flag = Qkill_emacs;
10549 Vinhibit_quit = Qnil;
10550 }
10533 } 10551 }
10534 10552
10535 /* Allow other handlers to handle this signal. */ 10553 /* Allow other handlers to handle this signal. */
diff --git a/src/w32fns.c b/src/w32fns.c
index b4192a5ffa6..745f561e6b1 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -11112,20 +11112,24 @@ emacs_abort (void)
11112 abort (); 11112 abort ();
11113 11113
11114 int button; 11114 int button;
11115 button = MessageBox (NULL, 11115
11116 "A fatal error has occurred!\n\n" 11116 if (noninteractive)
11117 "Would you like to attach a debugger?\n\n" 11117 button = IDNO;
11118 "Select:\n" 11118 else
11119 "YES -- to debug Emacs, or\n" 11119 button = MessageBox (NULL,
11120 "NO -- to abort Emacs and produce a backtrace\n" 11120 "A fatal error has occurred!\n\n"
11121 " (emacs_backtrace.txt in current directory)." 11121 "Would you like to attach a debugger?\n\n"
11122 "Select:\n"
11123 "YES -- to debug Emacs, or\n"
11124 "NO -- to abort Emacs and produce a backtrace\n"
11125 " (emacs_backtrace.txt in current directory)."
11122#if __GNUC__ 11126#if __GNUC__
11123 "\n\n(type \"gdb -p <emacs-PID>\" and\n" 11127 "\n\n(Before clicking YES, type\n"
11124 "\"continue\" inside GDB before clicking YES.)" 11128 "\"gdb -p <emacs-PID>\", then \"continue\" inside GDB.)"
11125#endif 11129#endif
11126 , "Emacs Abort Dialog", 11130 , "Emacs Abort Dialog",
11127 MB_ICONEXCLAMATION | MB_TASKMODAL 11131 MB_ICONEXCLAMATION | MB_TASKMODAL
11128 | MB_SETFOREGROUND | MB_YESNO); 11132 | MB_SETFOREGROUND | MB_YESNO);
11129 switch (button) 11133 switch (button)
11130 { 11134 {
11131 case IDYES: 11135 case IDYES: