From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alain Schneble Newsgroups: gmane.emacs.devel Subject: Re: SIGTRAP in kill emulation on Windows Date: Thu, 25 Aug 2016 22:02:37 +0200 Message-ID: <868tvkiplu.fsf@realize.ch> References: <86d1kwj37g.fsf@realize.ch> <83bn0gesab.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1472155444 28179 195.159.176.226 (25 Aug 2016 20:04:04 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 25 Aug 2016 20:04:04 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (windows-nt) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Aug 25 22:03:59 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bd0sU-0006e9-JI for ged-emacs-devel@m.gmane.org; Thu, 25 Aug 2016 22:03:54 +0200 Original-Received: from localhost ([::1]:57905 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bd0sS-0005hC-48 for ged-emacs-devel@m.gmane.org; Thu, 25 Aug 2016 16:03:52 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52019) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bd0rr-0005gv-IQ for emacs-devel@gnu.org; Thu, 25 Aug 2016 16:03:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bd0rm-0006ox-PD for emacs-devel@gnu.org; Thu, 25 Aug 2016 16:03:14 -0400 Original-Received: from clientmail.realize.ch ([46.140.89.53]:2221) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1bd0rg-0006lZ-F6; Thu, 25 Aug 2016 16:03:04 -0400 Original-Received: from rintintin.hq.realize.ch.lan.rit ([192.168.0.105]) by clientmail.realize.ch ; Thu, 25 Aug 2016 22:02:58 +0200 Original-Received: from MYNGB (192.168.66.64) by rintintin.hq.realize.ch.lan.rit (192.168.0.105) with Microsoft SMTP Server (TLS) id 15.0.516.32; Thu, 25 Aug 2016 22:02:38 +0200 In-Reply-To: <83bn0gesab.fsf@gnu.org> (Eli Zaretskii's message of "Thu, 25 Aug 2016 19:18:20 +0300") X-ClientProxiedBy: rintintin.hq.realize.ch.lan.rit (192.168.0.105) To rintintin.hq.realize.ch.lan.rit (192.168.0.105) X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] X-Received-From: 46.140.89.53 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:206804 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: > Thanks. I think this needs an entry in NEWS. Done. > We don't put in Emacs sources compile-time conditionals that depend on > the version of the OS on which Emacs is built: that would preclude the > (very popular on Windows) practice of building Emacs on one system, > and then using it on many others, possibly running other versions of > the OS. Thanks for this explanation and sorry that I didn't thought about this. I changed it to use run-time dynamic linking. > When the function is not available, you should assign ENOTSUP to > errno, not EINVAL, to make the error message more accurate. Done. > Please test what this functionality does when PID specifies a child > process of Emacs (which is tracked via the child_procs[] array), and > also when it specifies the calling Emacs process itself. If any of > these use cases cause any kind of trouble, we may wish to disallow > such usage, to prevent users from shooting themselves in the foot. Sending SIGTRAP to a process -- whether it's an unrelated, child or the calling Emacs process itself -- does not seem to have any effect as long as no debugger is attached to the receiving process. At least this is what I observe on Windows 10. Shall I test on other OS versions as well? If so, I would have to install say an Win XP first as I do not have one available right now. Unfortunately, on MSDN the remark on DebugBreakProcess says it causes the receiving process to terminate in most cases, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679298(v=vs.85).aspx But with all processes I tried, none of them was ever terminated. Many thanks for your help. Alain --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename="0001-Support-SIGTRAP-in-kill-emulation-on-Windows.patch" Content-Description: Support SIGTRAP in kill emulation on Windows >From ecf00b52957bb0bf15735180a67cc9ce7027ff19 Mon Sep 17 00:00:00 2001 From: Alain Schneble Date: Thu, 25 Aug 2016 21:31:48 +0200 Subject: [PATCH] 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. Windows versions prior to Windows XP that do not support DebugBreakProcess return -1 and errno set 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. --- etc/NEWS | 8 ++++++++ src/w32.c | 3 +++ src/w32proc.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 494a091..3d055fc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -599,6 +599,14 @@ still apply.) Previously, on MS-Windows this function converted slash characters in file names into backslashes. It no longer does that. +--- +** 'signal-process' supports SIGTRAP on Windows XP and later. +The 'kill' emulation on Windows now maps SIGTRAP to a call to Win32 +'DebugBreakProcess'. This causes the receiving process to break +execution and return control to the debugger. If no debugger is +attached to the receiving process, the call is typically ignored by +the receiving process. + * Installation Changes in Emacs 25.1 diff --git a/src/w32.c b/src/w32.c index 1db3426..355e7ca 100644 --- a/src/w32.c +++ b/src/w32.c @@ -330,6 +330,7 @@ static BOOL g_b_init_set_named_security_info_a; static BOOL g_b_init_get_adapters_info; BOOL g_b_init_compare_string_w; +BOOL g_b_init_debug_break_process; /* BEGIN: Wrapper functions around OpenProcessToken @@ -9636,6 +9637,7 @@ globals_of_w32 (void) g_b_init_get_process_working_set_size = 0; g_b_init_global_memory_status = 0; g_b_init_global_memory_status_ex = 0; + g_b_init_debug_break_process = 0; g_b_init_equal_sid = 0; g_b_init_copy_sid = 0; g_b_init_get_length_sid = 0; @@ -9653,6 +9655,7 @@ globals_of_w32 (void) g_b_init_set_named_security_info_a = 0; g_b_init_get_adapters_info = 0; g_b_init_compare_string_w = 0; + g_b_init_debug_break_process = 0; num_of_processors = 0; /* The following sets a handler for shutdown notifications for console apps. This actually applies to Emacs in both console and diff --git a/src/w32proc.c b/src/w32proc.c index 11a121f..bb637bc 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -66,6 +66,8 @@ along with GNU Emacs. If not, see . */ + (filedata).file_base)) extern BOOL g_b_init_compare_string_w; +extern BOOL g_b_init_debug_break_process; + int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, struct timespec *, void *); @@ -2494,6 +2496,9 @@ find_child_console (HWND hwnd, LPARAM arg) return TRUE; } +typedef BOOL (WINAPI * DebugBreakProcess_Proc) ( + HANDLE hProcess); + /* Emulate 'kill', but only for other processes. */ int sys_kill (pid_t pid, int sig) @@ -2507,9 +2512,9 @@ sys_kill (pid_t pid, int sig) if (pid < 0) pid = -pid; - /* Only handle signals that will result in the process dying */ + /* Only handle signals that can be mapped to a similar behavior on Windows */ if (sig != 0 - && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) + && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP && sig != SIGTRAP) { errno = EINVAL; return -1; @@ -2552,7 +2557,11 @@ sys_kill (pid_t pid, int sig) close the selected frame, which does not necessarily terminates Emacs. But then we are not supposed to call sys_kill with our own PID. */ - proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid); + + DWORD desiredAccess = + (sig == SIGTRAP) ? PROCESS_ALL_ACCESS : PROCESS_TERMINATE; + + proc_hand = OpenProcess (desiredAccess, 0, pid); if (proc_hand == NULL) { errno = EPERM; @@ -2648,6 +2657,43 @@ sys_kill (pid_t pid, int sig) rc = -1; } } + else if (sig == SIGTRAP) + { + static DebugBreakProcess_Proc s_pfn_Debug_Break_Process = NULL; + + if (g_b_init_debug_break_process == 0) + { + g_b_init_debug_break_process = 1; + s_pfn_Debug_Break_Process = (DebugBreakProcess_Proc) + GetProcAddress (GetModuleHandle ("kernel32.dll"), + "DebugBreakProcess"); + } + + if (s_pfn_Debug_Break_Process == NULL) + { + errno = ENOTSUP; + rc = -1; + } + else if (!s_pfn_Debug_Break_Process (proc_hand)) + { + DWORD err = GetLastError (); + + DebPrint (("sys_kill.DebugBreakProcess return %d " + "for pid %lu\n", err, pid)); + + switch (err) + { + case ERROR_ACCESS_DENIED: + errno = EPERM; + break; + default: + errno = EINVAL; + break; + } + + rc = -1; + } + } else { if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) -- 2.8.1.windows.1 --=-=-=--