bug-make
[Top][All Lists]
Advanced

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

[bug #61409] The code used to create sub-processes on Windows triggers t


From: Liviu Ionescu
Subject: [bug #61409] The code used to create sub-processes on Windows triggers the spawnve() issue
Date: Sun, 28 Nov 2021 19:53:47 -0500 (EST)
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15

Follow-up Comment #6, bug #61409 (project make):

Now I have a slightly better understanding of the problem, although I had no
time to experiment anything yet.

The real problem is in Microsoft UCRT, which has a bug in the code managing
the environment.

Unfortunately, even if Microsoft will fix the bug tomorrow, we still have to
deal with millions of Windows instances which exhibit the bug. And in this
respect, all programs that spawn children processes should consider
workarounds, including GNU make.

If my understanding is correct (based on the explanations I received from
someone much more knowledgeable than myself), the problem is related to the
way the environment is understood by Microsoft. 

---
Internally, the "environment" in a Windows process consists of a little more
than what you see in the standard C envp array. If you run
GetEnvironmentStringsA/W and iterate over it, you'll see the normal
environment variables, but also a few other ones, like these:

=::=::\
=C:=C:\code\ms-spawn-issue\sources\spawn
=ExitCode=00000000

These are special vars that start with an '=' - apparently the include
information about things like which directory is the "current directory" on
each drive letter.

When UCRT's spawn() tries to create a process, it wants to include these extra
variables from the current environment (from GetEnvironmentStringsA/W) on top
of the variables you provide in the 'envp' parameter.

When make starts its subprocesses, it does that by calling CreateProcess() and
passing in a string with the desired environment, but it doesn't know/care
about this kind of extra variables. So processes launched by make are missing
these extra variables in GetEnvironmentStringsA/W.

When launching a process with CreateProcess() and passing NULL to the
environment parameter, or passing NULL to the envp parameter to spawn, there's
no issue (the current exact environment is passed on). But if UCRT's spawn is
called in an environment that is missing these extra variables, it crashes.
---

So, if make creates sub-processes with a custom environment (i.e. does not
pass NULL to inherit the parent), those processes cannot use UCRT to create
sub-processes.

The same applies to sh.exe which spawns, for example, the compiler, to the
compiler who spawns the internal steps, and so on.

The workaround is relatively simple. The only known way that is guaranteed to
work is to pass a NULL environment, which means to inherit the environment
from the parent.

This means that instead of creating a custom environment, the parent must
temporarily adjust its own environment to match the desired one, spawn the
process, and restore the initial environment.

I did not check the code used by make, but if it passes a custom environment
and not a NULL, its children are affected by this Windows bug.

Regarding the question related to UCRT vs MSVCRT, the use of MSVCRT was
deprecated about 10 years ago when UCRT was introduced. mingw-w64 already
implements UCRT for some time, and it is very likely to become the default in
future mingw-w64 releases, since the MSVCRT code has many limitations and is
no longer maintained. All recent binary toolchain distributions (both clang
and gcc) produce binaries the use UCRT.

Thus the suggestion to stick to MSVCRT is not realistic.

Sure, you can close the issue, but this will not solve the problem.



    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?61409>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

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