unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable
@ 2017-06-29  9:41 Saulius Menkevičius
  2017-06-29 14:24 ` Eli Zaretskii
  0 siblings, 1 reply; 4+ messages in thread
From: Saulius Menkevičius @ 2017-06-29  9:41 UTC (permalink / raw)
  To: 27527

[-- Attachment #1: Type: text/plain, Size: 6621 bytes --]

Hello,

The issue was encountered when debugging a problem with omnisharp-emacs
package where starting a server process (written for and running in a  .NET/CLR VM)
crashes emacs with a segfault.

Recompiling with -g -O0 has revealed a problem in implementation of
w32_executable_type in src/w32proc.c where the code is attempting to list
DLL imports in a binary but the import table points to NULL. This code works for
.NET binaries compiled for x86 so the problem is specific to 64 bit Windows / .NET DLLs.

The callstack of a crash is below and I have a patch attached that fixes the problem. 
The patch applies cleanly to both master and emacs-25 branches.

I am omitting any standard report-emacs-bug information from below as I
am submitting this report from a different machine than the one that experiences
the problem.

Hopefully that is not a big issue.

======= 8< ===========
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) bt
#0  0x000007fefd9b31f3 in KERNELBASE!DebugBreak () from /c/Windows/system32/KERNELBASE.dll
#1  0x000000040023c953 in emacs_abort () at ../../emacs/src/w32fns.c:10923
#2  0x00000004000fe2ec in terminate_due_to_signal (sig=11, backtrace_limit=40) at ../../emacs/src/emacs.c:394
#3  0x0000000400123f15 in handle_fatal_signal (sig=11) at ../../emacs/src/sysdep.c:1714
#4  0x0000000400123ee5 in deliver_thread_signal (sig=11, handler=0x400123efd <handle_fatal_signal>) at ../../emacs/src/sysdep.c:1688
#5  0x0000000400123f51 in deliver_fatal_thread_signal (sig=11) at ../../emacs/src/sysdep.c:1726
#6  0x00000004002a5ea8 in _gnu_exception_handler (exception_data=0x82aff0) at C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt_handler.c:223
#7  0x0000000077bf7958 in ntdll!__C_specific_handler () from /c/Windows/SYSTEM32/ntdll.dll
#8  0x0000000077c0812d in ntdll!RtlDecodePointer () from /c/Windows/SYSTEM32/ntdll.dll
#9  0x0000000077bf855f in ntdll!RtlUnwindEx () from /c/Windows/SYSTEM32/ntdll.dll
#10 0x0000000077c2bcb8 in ntdll!KiUserExceptionDispatcher () from /c/Windows/SYSTEM32/ntdll.dll
#11 0x0000000400275bc0 in w32_executable_type (filename=0x82bfc0 "c:\\csharp\\omnisharp\\omnisharp.exe", is_dos_app=0x82c134, is_cygnus_app=0x82c130, is_msys_app=0x82c12c, is_gui_app=0x82c128) at ../../emacs/src/w32proc.c:1626
#12 0x0000000400276148 in sys_spawnve (mode=1, cmdname=0x82bfc0 "c:\\csharp\\omnisharp\\omnisharp.exe", argv=0x82c590, envp=0x82c250) at ../../emacs/src/w32proc.c:1802
#13 0x000000040020bf9e in child_setup (in=3, out=6, err=6, new_argv=0x82c590, set_pgrp=true, current_dir=...) at ../../emacs/src/callproc.c:1329
#14 0x00000004001fea90 in create_process (process=..., new_argv=0x82c590, current_dir=...) at ../../emacs/src/process.c:2182
#15 0x00000004001fe685 in Fmake_process (nargs=6, args=0x82c958) at ../../emacs/src/process.c:1904
#16 0x00000004001ac435 in funcall_subr (subr=0x4005df370 <Smake_process>, numargs=6, args=0x82c958) at ../../emacs/src/eval.c:2802
#17 0x00000004001ac156 in Ffuncall (nargs=7, args=0x82c950) at ../../emacs/src/eval.c:2747
#18 0x00000004001ab60b in Fapply (nargs=2, args=0x82cbf0) at ../../emacs/src/eval.c:2378
#19 0x00000004001ac435 in funcall_subr (subr=0x4005dc8d0 <Sapply>, numargs=2, args=0x82cbf0) at ../../emacs/src/eval.c:2802
#20 0x00000004001ac156 in Ffuncall (nargs=3, args=0x82cbe8) at ../../emacs/src/eval.c:2747
#21 0x00000004001f7012 in exec_byte_code (bytestr=..., vector=..., maxdepth=..., args_template=..., nargs=3, args=0x82d2c8) at ../../emacs/src/bytecode.c:641
#22 0x00000004001acb81 in funcall_lambda (fun=..., nargs=3, arg_vector=0x82d2b0) at ../../emacs/src/eval.c:2948
#23 0x00000004001ac8d0 in apply_lambda (fun=..., args=..., count=14) at ../../emacs/src/eval.c:2884
#24 0x00000004001aaf60 in eval_sub (form=...) at ../../emacs/src/eval.c:2268
#25 0x00000004001aa3a5 in Feval (form=..., lexical=...) at ../../emacs/src/eval.c:2045
#26 0x00000004001ac525 in funcall_subr (subr=0x4005dc8a0 <Seval>, numargs=2, args=0x82d710) at ../../emacs/src/eval.c:2824
#27 0x00000004001ac156 in Ffuncall (nargs=3, args=0x82d708) at ../../emacs/src/eval.c:2747
#28 0x00000004001f7012 in exec_byte_code (bytestr=..., vector=..., maxdepth=..., args_template=..., nargs=1, args=0x82de70) at ../../emacs/src/bytecode.c:641
#29 0x00000004001acb81 in funcall_lambda (fun=..., nargs=1, arg_vector=0x82de68) at ../../emacs/src/eval.c:2948
#30 0x00000004001ac19a in Ffuncall (nargs=2, args=0x82de60) at ../../emacs/src/eval.c:2749
#31 0x00000004001f7012 in exec_byte_code (bytestr=..., vector=..., maxdepth=..., args_template=..., nargs=1, args=0x82e768) at ../../emacs/src/bytecode.c:641
#32 0x00000004001acb81 in funcall_lambda (fun=..., nargs=1, arg_vector=0x82e760) at ../../emacs/src/eval.c:2948
#33 0x00000004001ac19a in Ffuncall (nargs=2, args=0x82e758) at ../../emacs/src/eval.c:2749
#34 0x00000004001a3c25 in Ffuncall_interactively (nargs=2, args=0x82e758) at ../../emacs/src/callint.c:252
#35 0x00000004001ac435 in funcall_subr (subr=0x4005dc2c8 <Sfuncall_interactively>, numargs=2, args=0x82e758) at ../../emacs/src/eval.c:2802
#36 0x00000004001ac156 in Ffuncall (nargs=3, args=0x82e750) at ../../emacs/src/eval.c:2747
#37 0x00000004001a63fb in Fcall_interactively (function=..., record_flag=..., keys=...) at ../../emacs/src/callint.c:844
#38 0x00000004001ac551 in funcall_subr (subr=0x4005dc2f8 <Scall_interactively>, numargs=3, args=0x82ec70) at ../../emacs/src/eval.c:2827
#39 0x00000004001ac156 in Ffuncall (nargs=4, args=0x82ec68) at ../../emacs/src/eval.c:2747
#40 0x00000004001f7012 in exec_byte_code (bytestr=..., vector=..., maxdepth=..., args_template=..., nargs=1, args=0x82f450) at ../../emacs/src/bytecode.c:641
#41 0x00000004001acb81 in funcall_lambda (fun=..., nargs=1, arg_vector=0x82f448) at ../../emacs/src/eval.c:2948
#42 0x00000004001ac19a in Ffuncall (nargs=2, args=0x82f440) at ../../emacs/src/eval.c:2749
#43 0x00000004001abbcd in call1 (fn=..., arg1=...) at ../../emacs/src/eval.c:2609
#44 0x0000000400103dd5 in command_loop_1 () at ../../emacs/src/keyboard.c:1486
#45 0x00000004001a8c50 in internal_condition_case (bfun=0x4001034d3 <command_loop_1>, handlers=..., hfun=0x400102ad0 <cmd_error>) at ../../emacs/src/eval.c:1326
#46 0x000000040010314b in command_loop_2 (ignore=...) at ../../emacs/src/keyboard.c:1114
#47 0x00000004001a850e in internal_catch (tag=..., func=0x400103119 <command_loop_2>, arg=...) at ../../emacs/src/eval.c:1091
#48 0x000000040010309e in command_loop () at ../../emacs/src/keyboard.c:1093
#49 0x0000000000000000 in ?? ()
======= 8< =========


[-- Attachment #2: windows-x64-dotnet-exe-crash-fix.patch --]
[-- Type: application/octet-stream, Size: 3256 bytes --]

diff --git a/src/w32proc.c b/src/w32proc.c
index 0aa248a6f7..f686eaf4a1 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1622,36 +1622,41 @@ w32_executable_type (char * filename,
               /* Look for Cygwin DLL in the DLL import list. */
               IMAGE_DATA_DIRECTORY import_dir =
                 data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT];
-              IMAGE_IMPORT_DESCRIPTOR * imports =
-		RVA_TO_PTR (import_dir.VirtualAddress,
-			    rva_to_section (import_dir.VirtualAddress,
-					    nt_header),
-			    executable);
 
-              for ( ; imports->Name; imports++)
+	      /* Import directory can be missing on .NET dlls */
+	      if (import_dir.VirtualAddress != 0)
                 {
-		  IMAGE_SECTION_HEADER * section =
-		    rva_to_section (imports->Name, nt_header);
-                  char * dllname = RVA_TO_PTR (imports->Name, section,
-                                               executable);
-
-                  /* The exact name of the Cygwin DLL has changed with
-                     various releases, but hopefully this will be
-                     reasonably future-proof.  */
-                  if (strncmp (dllname, "cygwin", 6) == 0)
+                  IMAGE_IMPORT_DESCRIPTOR * imports =
+                    RVA_TO_PTR (import_dir.VirtualAddress,
+                                rva_to_section (import_dir.VirtualAddress,
+                                                nt_header),
+                                executable);
+
+                  for ( ; imports->Name; imports++)
                     {
-                      *is_cygnus_app = TRUE;
-                      break;
-                    }
-		  else if (strncmp (dllname, "msys-", 5) == 0)
-		    {
-		      /* This catches both MSYS 1.x and MSYS2
-			 executables (the DLL name is msys-1.0.dll and
-			 msys-2.0.dll, respectively).  There doesn't
-			 seem to be a reason to distinguish between
-			 the two, for now.  */
-		      *is_msys_app = TRUE;
-		      break;
+                      IMAGE_SECTION_HEADER * section =
+                        rva_to_section (imports->Name, nt_header);
+                      char * dllname = RVA_TO_PTR (imports->Name, section,
+                                                   executable);
+
+                      /* The exact name of the Cygwin DLL has changed with
+                         various releases, but hopefully this will be
+                         reasonably future-proof.  */
+                      if (strncmp (dllname, "cygwin", 6) == 0)
+                        {
+                          *is_cygnus_app = TRUE;
+                          break;
+                        }
+                      else if (strncmp (dllname, "msys-", 5) == 0)
+                        {
+                           /* This catches both MSYS 1.x and MSYS2
+                              executables (the DLL name is msys-1.0.dll and
+                              msys-2.0.dll, respectively).  There doesn't
+                              seem to be a reason to distinguish between
+                              the two, for now.  */
+                           *is_msys_app = TRUE;
+                           break;
+                        }
 		    }
                 }
             }

[-- Attachment #3: Type: text/plain, Size: 38 bytes --]



Thank you,

BR,
-Saulius Menkevicius

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable
  2017-06-29  9:41 bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable Saulius Menkevičius
@ 2017-06-29 14:24 ` Eli Zaretskii
  2017-06-29 16:10   ` Saulius Menkevičius
  0 siblings, 1 reply; 4+ messages in thread
From: Eli Zaretskii @ 2017-06-29 14:24 UTC (permalink / raw)
  To: Saulius Menkevičius; +Cc: 27527

> From: Saulius Menkevičius <saulius.menkevicius@gmail.com>
> Date: Thu, 29 Jun 2017 12:41:55 +0300
> 
> The issue was encountered when debugging a problem with omnisharp-emacs
> package where starting a server process (written for and running in a  .NET/CLR VM)
> crashes emacs with a segfault.
> 
> Recompiling with -g -O0 has revealed a problem in implementation of
> w32_executable_type in src/w32proc.c where the code is attempting to list
> DLL imports in a binary but the import table points to NULL. This code works for
> .NET binaries compiled for x86 so the problem is specific to 64 bit Windows / .NET DLLs.
> 
> The callstack of a crash is below and I have a patch attached that fixes the problem. 
> The patch applies cleanly to both master and emacs-25 branches.

Thanks.

Can you send the diffs generated with the -b switch?  I think all you
did was to condition the use of the import directory on its being
non-NULL, but it's hard to tell judging just by the diffs you posted.





^ permalink raw reply	[flat|nested] 4+ messages in thread

* bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable
  2017-06-29 14:24 ` Eli Zaretskii
@ 2017-06-29 16:10   ` Saulius Menkevičius
  2017-07-09 18:19     ` Eli Zaretskii
  0 siblings, 1 reply; 4+ messages in thread
From: Saulius Menkevičius @ 2017-06-29 16:10 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 27527

[-- Attachment #1: Type: text/plain, Size: 19 bytes --]

Sure,

Here it is:

[-- Attachment #2: windows-x64-dotnet-exe-crash-fix-b.patch --]
[-- Type: application/octet-stream, Size: 818 bytes --]

diff --git a/src/w32proc.c b/src/w32proc.c
index 200c2b2ba4..2d303e9139 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1618,6 +1618,10 @@ w32_executable_type (char * filename,
               /* Look for Cygwin DLL in the DLL import list. */
               IMAGE_DATA_DIRECTORY import_dir =
                 data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT];
+
+	      /* Import directory can be missing on .NET dlls */
+	      if (import_dir.VirtualAddress != 0)
+                {
                   IMAGE_IMPORT_DESCRIPTOR * imports =
                     RVA_TO_PTR (import_dir.VirtualAddress,
                                 rva_to_section (import_dir.VirtualAddress,
@@ -1653,6 +1657,7 @@ w32_executable_type (char * filename,
                 }
             }
   	}
+    }
 
 unwind:
   close_file_data (&executable);

[-- Attachment #3: Type: text/plain, Size: 1114 bytes --]



> Am 29.06.2017 um 17:24 schrieb Eli Zaretskii <eliz@gnu.org>:
> 
>> From: Saulius Menkevičius <saulius.menkevicius@gmail.com>
>> Date: Thu, 29 Jun 2017 12:41:55 +0300
>> 
>> The issue was encountered when debugging a problem with omnisharp-emacs
>> package where starting a server process (written for and running in a  .NET/CLR VM)
>> crashes emacs with a segfault.
>> 
>> Recompiling with -g -O0 has revealed a problem in implementation of
>> w32_executable_type in src/w32proc.c where the code is attempting to list
>> DLL imports in a binary but the import table points to NULL. This code works for
>> .NET binaries compiled for x86 so the problem is specific to 64 bit Windows / .NET DLLs.
>> 
>> The callstack of a crash is below and I have a patch attached that fixes the problem. 
>> The patch applies cleanly to both master and emacs-25 branches.
> 
> Thanks.
> 
> Can you send the diffs generated with the -b switch?  I think all you
> did was to condition the use of the import directory on its being
> non-NULL, but it's hard to tell judging just by the diffs you posted.


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable
  2017-06-29 16:10   ` Saulius Menkevičius
@ 2017-07-09 18:19     ` Eli Zaretskii
  0 siblings, 0 replies; 4+ messages in thread
From: Eli Zaretskii @ 2017-07-09 18:19 UTC (permalink / raw)
  To: Saulius Menkevičius; +Cc: 27527-done

> From: Saulius Menkevičius <saulius.menkevicius@gmail.com>
> Date: Thu, 29 Jun 2017 19:10:00 +0300
> Cc: 27527@debbugs.gnu.org
> 
> Sure,
> 
> Here it is:

Thanks, pushed to the master branch.  Sorry for the delay.





^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-07-09 18:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-29  9:41 bug#27527: 25.2; start-process crash on Windows with 64bit .NET executable Saulius Menkevičius
2017-06-29 14:24 ` Eli Zaretskii
2017-06-29 16:10   ` Saulius Menkevičius
2017-07-09 18:19     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).