diff options
| author | Alain Schneble | 2016-10-08 16:52:40 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2016-10-08 16:52:40 +0300 |
| commit | f3eedc7e68d0e8b97425b72d691593d06639df88 (patch) | |
| tree | 8382915bdc2da6b10293e2c86c8b1306e6567373 /src | |
| parent | 67d14c8222c05ac20229f71a2cf40eb9e3efa053 (diff) | |
| download | emacs-f3eedc7e68d0e8b97425b72d691593d06639df88.tar.gz emacs-f3eedc7e68d0e8b97425b72d691593d06639df88.zip | |
Support SIGTRAP in kill emulation on Windows
* src/w32proc.c (sys_kill): Translate SIGTRAP signal into a call to
'DebugBreakProcess' to cause a breakpoint exception to occur in the
specified process. On Windows versions prior to Windows XP that do
not support 'DebugBreakProcess' return -1 and set errno to ENOTSUP
(as opposed to EINVAL before this change).
* src/w32proc.c: Add typedef for 'DebugBreakProcess' function pointer
and global variable to track state of run-time dynamic linking of this
function.
* etc/NEWS: Add entry to document that 'signal-process' now supports
SIGTRAP.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 2 | ||||
| -rw-r--r-- | src/w32proc.c | 52 |
2 files changed, 51 insertions, 3 deletions
| @@ -334,6 +334,7 @@ static BOOL g_b_init_set_named_security_info_a; | |||
| 334 | static BOOL g_b_init_get_adapters_info; | 334 | static BOOL g_b_init_get_adapters_info; |
| 335 | 335 | ||
| 336 | BOOL g_b_init_compare_string_w; | 336 | BOOL g_b_init_compare_string_w; |
| 337 | BOOL g_b_init_debug_break_process; | ||
| 337 | 338 | ||
| 338 | /* | 339 | /* |
| 339 | BEGIN: Wrapper functions around OpenProcessToken | 340 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -9657,6 +9658,7 @@ globals_of_w32 (void) | |||
| 9657 | g_b_init_set_named_security_info_a = 0; | 9658 | g_b_init_set_named_security_info_a = 0; |
| 9658 | g_b_init_get_adapters_info = 0; | 9659 | g_b_init_get_adapters_info = 0; |
| 9659 | g_b_init_compare_string_w = 0; | 9660 | g_b_init_compare_string_w = 0; |
| 9661 | g_b_init_debug_break_process = 0; | ||
| 9660 | num_of_processors = 0; | 9662 | num_of_processors = 0; |
| 9661 | /* The following sets a handler for shutdown notifications for | 9663 | /* The following sets a handler for shutdown notifications for |
| 9662 | console apps. This actually applies to Emacs in both console and | 9664 | console apps. This actually applies to Emacs in both console and |
diff --git a/src/w32proc.c b/src/w32proc.c index aef4e44d73a..189034c4e2d 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -69,6 +69,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 69 | + (filedata).file_base)) | 69 | + (filedata).file_base)) |
| 70 | 70 | ||
| 71 | extern BOOL g_b_init_compare_string_w; | 71 | extern BOOL g_b_init_compare_string_w; |
| 72 | extern BOOL g_b_init_debug_break_process; | ||
| 73 | |||
| 72 | int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | 74 | int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, |
| 73 | struct timespec *, void *); | 75 | struct timespec *, void *); |
| 74 | 76 | ||
| @@ -2497,6 +2499,9 @@ find_child_console (HWND hwnd, LPARAM arg) | |||
| 2497 | return TRUE; | 2499 | return TRUE; |
| 2498 | } | 2500 | } |
| 2499 | 2501 | ||
| 2502 | typedef BOOL (WINAPI * DebugBreakProcess_Proc) ( | ||
| 2503 | HANDLE hProcess); | ||
| 2504 | |||
| 2500 | /* Emulate 'kill', but only for other processes. */ | 2505 | /* Emulate 'kill', but only for other processes. */ |
| 2501 | int | 2506 | int |
| 2502 | sys_kill (pid_t pid, int sig) | 2507 | sys_kill (pid_t pid, int sig) |
| @@ -2510,9 +2515,9 @@ sys_kill (pid_t pid, int sig) | |||
| 2510 | if (pid < 0) | 2515 | if (pid < 0) |
| 2511 | pid = -pid; | 2516 | pid = -pid; |
| 2512 | 2517 | ||
| 2513 | /* Only handle signals that will result in the process dying */ | 2518 | /* Only handle signals that can be mapped to a similar behavior on Windows */ |
| 2514 | if (sig != 0 | 2519 | if (sig != 0 |
| 2515 | && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) | 2520 | && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP && sig != SIGTRAP) |
| 2516 | { | 2521 | { |
| 2517 | errno = EINVAL; | 2522 | errno = EINVAL; |
| 2518 | return -1; | 2523 | return -1; |
| @@ -2555,7 +2560,11 @@ sys_kill (pid_t pid, int sig) | |||
| 2555 | close the selected frame, which does not necessarily | 2560 | close the selected frame, which does not necessarily |
| 2556 | terminates Emacs. But then we are not supposed to call | 2561 | terminates Emacs. But then we are not supposed to call |
| 2557 | sys_kill with our own PID. */ | 2562 | sys_kill with our own PID. */ |
| 2558 | proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid); | 2563 | |
| 2564 | DWORD desiredAccess = | ||
| 2565 | (sig == SIGTRAP) ? PROCESS_ALL_ACCESS : PROCESS_TERMINATE; | ||
| 2566 | |||
| 2567 | proc_hand = OpenProcess (desiredAccess, 0, pid); | ||
| 2559 | if (proc_hand == NULL) | 2568 | if (proc_hand == NULL) |
| 2560 | { | 2569 | { |
| 2561 | errno = EPERM; | 2570 | errno = EPERM; |
| @@ -2651,6 +2660,43 @@ sys_kill (pid_t pid, int sig) | |||
| 2651 | rc = -1; | 2660 | rc = -1; |
| 2652 | } | 2661 | } |
| 2653 | } | 2662 | } |
| 2663 | else if (sig == SIGTRAP) | ||
| 2664 | { | ||
| 2665 | static DebugBreakProcess_Proc s_pfn_Debug_Break_Process = NULL; | ||
| 2666 | |||
| 2667 | if (g_b_init_debug_break_process == 0) | ||
| 2668 | { | ||
| 2669 | g_b_init_debug_break_process = 1; | ||
| 2670 | s_pfn_Debug_Break_Process = (DebugBreakProcess_Proc) | ||
| 2671 | GetProcAddress (GetModuleHandle ("kernel32.dll"), | ||
| 2672 | "DebugBreakProcess"); | ||
| 2673 | } | ||
| 2674 | |||
| 2675 | if (s_pfn_Debug_Break_Process == NULL) | ||
| 2676 | { | ||
| 2677 | errno = ENOTSUP; | ||
| 2678 | rc = -1; | ||
| 2679 | } | ||
| 2680 | else if (!s_pfn_Debug_Break_Process (proc_hand)) | ||
| 2681 | { | ||
| 2682 | DWORD err = GetLastError (); | ||
| 2683 | |||
| 2684 | DebPrint (("sys_kill.DebugBreakProcess return %d " | ||
| 2685 | "for pid %lu\n", err, pid)); | ||
| 2686 | |||
| 2687 | switch (err) | ||
| 2688 | { | ||
| 2689 | case ERROR_ACCESS_DENIED: | ||
| 2690 | errno = EPERM; | ||
| 2691 | break; | ||
| 2692 | default: | ||
| 2693 | errno = EINVAL; | ||
| 2694 | break; | ||
| 2695 | } | ||
| 2696 | |||
| 2697 | rc = -1; | ||
| 2698 | } | ||
| 2699 | } | ||
| 2654 | else | 2700 | else |
| 2655 | { | 2701 | { |
| 2656 | if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) | 2702 | if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) |