Bug
On Windows builds compiled with a non-MSVC toolchain (MINGW / clang, as shipped
by MSYS2), the os.exec*e and os.spawn*e variants crash with an access
violation whenever an env argument is passed. The non-env variants are fine.
This is the same defect as gh-67650 ("All os.exec*e variants crash on Windows",
formerly bpo-23462); it was closed as fixed in 3.6, but the fix does not cover
MINGW/clang builds, which still crash.
Reproducer
import os, sys
exe = os.path.join(os.path.dirname(sys.executable), "python.exe")
os.execve(exe, [exe, "-c", "pass"], {"PATH": os.environ["PATH"]})
$ python repro.py
Windows fatal exception: access violation
Current thread 0x000045cc (most recent call first):
File "repro.py", line 4 in <module>
$ echo $?
139
Measured (MINGW clang64 python 3.14.7, 20 runs each)
| Call |
Success |
os.execv(exe, argv) (no env) |
20/20 |
os.spawnv(P_WAIT, exe, argv) (no env) |
20/20 |
os.execve(exe, argv, env) |
0/20 |
os.spawnve(P_WAIT, exe, argv, env) |
0/20 |
Root cause
HAVE_WEXECV / HAVE_WSPAWNV are defined in Modules/posixmodule.c only for
the Microsoft compiler:
#elif defined( _MSC_VER)
/* Microsoft compiler */
...
# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
# define HAVE_WEXECV 1
# define HAVE_WSPAWNV 1
# endif
#endif
MINGW/clang does not define _MSC_VER, so HAVE_WEXECV is absent and the code
falls into the narrow branch. On Windows path->narrow is NULL (the path is
converted to wide), so the call faults (Modules/posixmodule.c, v3.14.0):
/* execv, line 7024 */
#ifdef HAVE_WEXECV
_wexecv(path->wide, argvlist);
#else
execv(path->narrow, argvlist); /* path->narrow == NULL -> crash */
#endif
/* execve, line 7112 */
#ifdef HAVE_WEXECV
_wexecve(path->wide, argvlist, envlist);
#else
execve(path->narrow, argvlist, envlist); /* crash */
#endif
Evidence the wide functions are available
MSYS2 pyconfig.h has HAVE_EXECV but not HAVE_WEXECV:
$ grep -n "WEXECV\|HAVE_EXECV" /clang64/include/python3.14/pyconfig.h
364:#define HAVE_EXECV 1 # <- no HAVE_WEXECV
Yet msvcrt exports all four wide calls:
>>> import ctypes
>>> for n in ("_wexecv", "_wexecve", "_wspawnv", "_wspawnve"):
... print(n, hasattr(ctypes.CDLL("msvcrt.dll"), n))
_wexecv True
_wexecve True
_wspawnv True
_wspawnve True
So the CRT supports the fix; only the compile-time gate is wrong for this
toolchain.
Suggested fix
Detect the wide CRT functions for non-MSVC Windows toolchains as well, instead
of gating HAVE_WEXECV / HAVE_WSPAWNV on _MSC_VER. If detection is awkward
in pyconfig, posixmodule.c could define them for MS_WINDOWS builds whose
CRT provides _wexecv/_wexecve/_wspawnv/_wspawnve.
Impact
Hard crash for any MINGW/clang Windows Python (MSYS2 clang64/ucrt64/mingw64)
code that uses os.execve/execvpe/spawnve. No pure-Python workaround for
exec*e (they replace the process); subprocess with env is a workaround.
Related: the same issue was reported downstream to MSYS2 —
msys2/MINGW-packages#32022
Bug
On Windows builds compiled with a non-MSVC toolchain (MINGW / clang, as shipped
by MSYS2), the
os.exec*eandos.spawn*evariants crash with an accessviolation whenever an
envargument is passed. The non-envvariants are fine.This is the same defect as gh-67650 ("All os.exec*e variants crash on Windows",
formerly bpo-23462); it was closed as fixed in 3.6, but the fix does not cover
MINGW/clang builds, which still crash.
Reproducer
Measured (MINGW clang64 python 3.14.7, 20 runs each)
os.execv(exe, argv)(no env)os.spawnv(P_WAIT, exe, argv)(no env)os.execve(exe, argv, env)os.spawnve(P_WAIT, exe, argv, env)Root cause
HAVE_WEXECV/HAVE_WSPAWNVare defined inModules/posixmodule.conly forthe Microsoft compiler:
MINGW/clang does not define
_MSC_VER, soHAVE_WEXECVis absent and the codefalls into the narrow branch. On Windows
path->narrowis NULL (the path isconverted to wide), so the call faults (
Modules/posixmodule.c, v3.14.0):Evidence the wide functions are available
MSYS2
pyconfig.hhasHAVE_EXECVbut notHAVE_WEXECV:Yet
msvcrtexports all four wide calls:So the CRT supports the fix; only the compile-time gate is wrong for this
toolchain.
Suggested fix
Detect the wide CRT functions for non-MSVC Windows toolchains as well, instead
of gating
HAVE_WEXECV/HAVE_WSPAWNVon_MSC_VER. If detection is awkwardin
pyconfig,posixmodule.ccould define them forMS_WINDOWSbuilds whoseCRT provides
_wexecv/_wexecve/_wspawnv/_wspawnve.Impact
Hard crash for any MINGW/clang Windows Python (MSYS2 clang64/ucrt64/mingw64)
code that uses
os.execve/execvpe/spawnve. No pure-Python workaround forexec*e(they replace the process);subprocesswithenvis a workaround.Related: the same issue was reported downstream to MSYS2 —
msys2/MINGW-packages#32022