My app (java based) launches python for Windows, which, in turn, calls os.spawnv
to launch another python.
From time to time I am having Access Violation exception.
00 005eedb0 763e68f3 ucrtbase!<lambda_7d9ee38b11181ddfdf5bd66394e53cb7>::operator()+0x1b
01 005eedfc 763e65d9 ucrtbase!construct_environment_block<char>+0xdb
02 005eee14 763e7aba ucrtbase!common_pack_argv_and_envp<char>+0x31
03 005eeebc 763e778a ucrtbase!execute_command<char>+0x62
04 005eeee8 763e8066 ucrtbase!common_spawnv<char>+0x13f
05 005eeef8 65a323d7 ucrtbase!_spawnve+0x16
06 005eef38 65a360c6 python35!os_spawnve_impl(int mode = 0n0, struct _object * path = 0x03adfde0, struct _object * argv = 0x03b258a0, struct _object * env = 0x03b25a80)+0x1a7 [c:\build\cpython\modules\posixmodule.c @ 5299]
I've set bp on c:\build\cpython\modules\posixmodule.c @ 5299
and here is what I see in python sources
Py_BEGIN_ALLOW_THREADS
spawnval = _spawnve(mode, path_char, argvlist, envlist);
Py_END_ALLOW_THREADS
I've checked all arguments twice: they are ok. mode
is 0, path_char
is path to my interpeter, argvlist
and envlist
are both char**
: NULL-terminated arrays of NULL-teminated strings.
So, it is not python fault.
I know that _spawnve
is not thread safe, but there is only one thread.
I do not have sources nor private symbols for MS ucrtbase. What is the right approach to investigate it?
--
What is the difference between ucrtbased.dll
and ucrtbase.dll
?
Should I compile Python against ucrtbased.dll to find more symbols?
I have just encountered the same problem while trying to build SciPy; an access violation is thrown as part of setup.py trying to
spawnve()
a C compiler.I haven't gotten to the bottom of it yet, but stepping through the disassembly, in my case at least. Here's what happens:
Calls
get_environment_from_os()
which gives you a pointer to the current process's environment variables.Iterates through this list of null-terminated strings looking for environment variables whose name starts with an '
=
'Apparently this is Windows's way of expressing the set of current directories, e.g. there should be an environment variable '
=c:
' with a value like "c:\mystuff
"It never finds any, and trundling off into uninitialized memory in its futile quest.
Boom.
Inspecting the memory address returned by
get_environment_from_os()
shows me a pretty sane looking list of environment variables, but none whose key begins with an '=
' character.I'm still digging into exactly why and how things get into this state; it doesn't always seem to happen which makes me suspect threads, but like you, I can't find any evidence to back this up; though I don't have intimate knowledge about how
distutils
works.