diff options
| author | Eli Zaretskii | 2023-01-22 15:07:55 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2023-01-22 15:09:21 +0200 |
| commit | 8e83604dfe01e0ea56569c1bc129ecbc67583447 (patch) | |
| tree | 3dab806ad5ea0adc8fbb6709281c76486318464a | |
| parent | 808e101fabec64a2f7a42dd9d9207ebd402ead4f (diff) | |
| download | emacs-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.c | 44 | ||||
| -rw-r--r-- | src/w32fns.c | 28 |
2 files changed, 47 insertions, 25 deletions
| @@ -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 | |||
| 10517 | extern DWORD dwMainThreadId; | ||
| 10518 | |||
| 10516 | static BOOL WINAPI | 10519 | static BOOL WINAPI |
| 10517 | shutdown_handler (DWORD type) | 10520 | shutdown_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: |