Mail Archives: cygwin/2024/02/02/12:23:38
On Feb 2 14:56, David Allsopp via Cygwin wrote:
> On Fri, 2 Feb 2024 at 14:18, Corinna Vinschen via Cygwin wrote:
> > On Feb 2 13:35, David Allsopp via Cygwin wrote:
> > > Not really suggesting it be done this way (it feels more complicated
> > > than just reverting the change), but in some ways perhaps Cygwin
> > > should be using GetErrorMode on startup and instead of not inheriting
> > > it, ensuring that it sets whatever it received? i.e. just before the
> > > call to CreateProcess for a non-Cygwin binary, Cygwin restores the
> > > error mode (for that thread only) to the value read at startup, calls
> > > CreateProcess and then sets the error mode back.
> >
> > This sounds like a good ide, but...
> >
> > Is it actually a safe bet that the error mode set by SetThreadErrorMode
> > is then propagated as process error mode to the child process?
> >
> > I have to ask that because Microsoft conveniently forgot to document
> > this scenario in the MSDN docs.
>
> :o) Never knowingly clear, are they! It would seem to be the intent of
> SetThreadErrorMode that it would behave that way but who knows.
>
> Happy to set up a quick experiment to check that it does work (i.e.
> the invoked process has GetErrorMode set as expected) and that there's
> no possible race between two threads in the calling process with
> differing values (i.e. that having SEM_FAILCRITICALERRORS in one
> thread and not in another behaves as expected. If it does appear to
> work consistently, would you be willing to go down this route? Happy
> to do the patch, although it'd be very helpful to have a couple of
> pointers: I'm guessing the value would want to be captured just before
> the one place where SetErrorMode is already called, but in which
> structure should it then be stashed away to be reused in spawn?
Wanna try this? It ignores the case of starting a process
under another user account for now, but that can be added easily
if this proves to work as expected.
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index a40129c22232..f1017e69b6b2 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -718,7 +718,8 @@ dll_crt0_0 ()
init_windows_system_directory ();
initial_env ();
- SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+ orig_proc_error_mode = SetErrorMode (SEM_FAILCRITICALERRORS
+ | SEM_NOGPFAULTERRORBOX);
lock_process::init ();
user_data->impure_ptr = _impure_ptr;
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index 885ada85e7b8..d2861ba98b42 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -28,6 +28,7 @@ PWCHAR windows_directory = windows_directory_buf + 4;
UINT windows_directory_length;
UNICODE_STRING windows_directory_path;
WCHAR global_progname[NT_MAX_PATH];
+UINT orig_proc_error_mode;
/* program exit the program */
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 8a2db5cf72e2..df83f25d13c6 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -648,6 +648,10 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
&& !::cygheap->user.groups.issetgroups ()
&& !::cygheap->user.setuid_to_restricted))
{
+ UINT orig_thread_error_mode = SEM_FAILCRITICALERRORS
+ | SEM_NOGPFAULTERRORBOX;
+ if (!iscygwin ())
+ SetThreadErrorMode (orig_proc_error_mode, &orig_thread_error_mode);
rc = CreateProcessW (runpath, /* image name w/ full path */
cmd.wcs (wcmd), /* what was passed to exec */
sa, /* process security attrs */
@@ -658,6 +662,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
NULL,
&si,
&pi);
+ if (!iscygwin ())
+ SetThreadErrorMode (orig_thread_error_mode, NULL);
}
else
{
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple
- Raw text -