emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 8e83604dfe0: Avoid crashes in batch Emacs sub-processes on MS-W


From: Eli Zaretskii
Subject: emacs-29 8e83604dfe0: Avoid crashes in batch Emacs sub-processes on MS-Windows
Date: Sun, 22 Jan 2023 08:09:32 -0500 (EST)

branch: emacs-29
commit 8e83604dfe01e0ea56569c1bc129ecbc67583447
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    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)
---
 src/w32.c    | 44 +++++++++++++++++++++++++++++++-------------
 src/w32fns.c | 28 ++++++++++++++++------------
 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)
   }
 }
 
-/*
-        shutdown_handler ensures that buffers' autosave files are
-       up to date when the user logs off, or the system shuts down.
-*/
+/* shutdown_handler ensures that buffers' autosave files are up to
+   date when the user logs off, or the system shuts down.  It also
+   shuts down Emacs when we get killed by another Emacs process, in
+   which case we get the CTRL_CLOSE_EVENT.  */
+
+extern DWORD dwMainThreadId;
+
 static BOOL WINAPI
 shutdown_handler (DWORD type)
 {
@@ -10521,15 +10524,30 @@ shutdown_handler (DWORD type)
       || type == CTRL_LOGOFF_EVENT    /* User logs off.  */
       || type == CTRL_SHUTDOWN_EVENT) /* User shutsdown.  */
     {
-      /* If we are being shut down in noninteractive mode, we don't
-        care about the message stack, so clear it to avoid abort in
-        shut_down_emacs.  This happens when an noninteractive Emacs
-        is invoked as a subprocess of Emacs, and the parent wants to
-        kill us, e.g. because it's about to exit.  */
-      if (noninteractive)
-       clear_message_stack ();
-      /* Shut down cleanly, making sure autosave files are up to date.  */
-      shut_down_emacs (0, Qnil);
+      if (GetCurrentThreadId () == dwMainThreadId)
+       {
+         /* If we are being shut down in noninteractive mode, we don't
+            care about the message stack, so clear it to avoid abort in
+            shut_down_emacs.  This happens when an noninteractive Emacs
+            is invoked as a subprocess of Emacs, and the parent wants to
+            kill us, e.g. because it's about to exit.  */
+         if (noninteractive)
+           clear_message_stack ();
+         /* Shut down cleanly, making sure autosave files are up to date.  */
+         shut_down_emacs (0, Qnil);
+       }
+      {
+       /* This handler is run in a thread different from the main
+          thread.  (This is the normal situation when we are killed
+          by Emacs, for example, which sends us the WM_CLOSE
+          message).  We cannot possibly call functions like
+          shut_down_emacs or clear_message_stack in that case, since
+          the main (a.k.a. "Lisp") thread could be in the middle of
+          some Lisp program.  So instead we arrange for maybe_quit to
+          kill Emacs.  */
+       Vquit_flag = Qkill_emacs;
+       Vinhibit_quit = Qnil;
+      }
     }
 
   /* 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)
     abort ();
 
   int button;
-  button = MessageBox (NULL,
-                      "A fatal error has occurred!\n\n"
-                      "Would you like to attach a debugger?\n\n"
-                      "Select:\n"
-                      "YES -- to debug Emacs, or\n"
-                      "NO  -- to abort Emacs and produce a backtrace\n"
-                      "       (emacs_backtrace.txt in current directory)."
+
+  if (noninteractive)
+    button = IDNO;
+  else
+    button = MessageBox (NULL,
+                        "A fatal error has occurred!\n\n"
+                        "Would you like to attach a debugger?\n\n"
+                        "Select:\n"
+                        "YES -- to debug Emacs, or\n"
+                        "NO  -- to abort Emacs and produce a backtrace\n"
+                        "       (emacs_backtrace.txt in current directory)."
 #if __GNUC__
-                      "\n\n(type \"gdb -p <emacs-PID>\" and\n"
-                      "\"continue\" inside GDB before clicking YES.)"
+                        "\n\n(Before clicking YES, type\n"
+                        "\"gdb -p <emacs-PID>\", then \"continue\" inside 
GDB.)"
 #endif
-                      , "Emacs Abort Dialog",
-                      MB_ICONEXCLAMATION | MB_TASKMODAL
-                      | MB_SETFOREGROUND | MB_YESNO);
+                        , "Emacs Abort Dialog",
+                        MB_ICONEXCLAMATION | MB_TASKMODAL
+                        | MB_SETFOREGROUND | MB_YESNO);
   switch (button)
     {
     case IDYES:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]