emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master f3eedc7: Support SIGTRAP in kill emulation on Windo


From: Eli Zaretskii
Subject: [Emacs-diffs] master f3eedc7: Support SIGTRAP in kill emulation on Windows
Date: Sat, 8 Oct 2016 13:54:12 +0000 (UTC)

branch: master
commit f3eedc7e68d0e8b97425b72d691593d06639df88
Author: Alain Schneble <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 etc/NEWS      |   10 ++++++++++
 src/w32.c     |    2 ++
 src/w32proc.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 59fb72a..14450a6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -668,6 +668,16 @@ session and exits.  In particular, this will happen if you 
start
 emacs.exe from the Windows shell, then type Ctrl-C into that shell's
 window.
 
+---
+** 'signal-process' supports SIGTRAP on Windows XP and later.
+The 'kill' emulation on Windows now maps SIGTRAP to a call to the
+'DebugBreakProcess' API.  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.
+This is in contrast to the default action on POSIX Systems, where it
+causes the receiving process to terminate with a core dump if no
+debugger has been attached to it.
+
 
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/src/w32.c b/src/w32.c
index f911085..517e286 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -334,6 +334,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
@@ -9657,6 +9658,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 aef4e44..189034c 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/>.  */
            + (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 *);
 
@@ -2497,6 +2499,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)
@@ -2510,9 +2515,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;
@@ -2555,7 +2560,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;
@@ -2651,6 +2660,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)



reply via email to

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