Calling nt.execv works with a unicode string because it creates a bytes path via PyUnicode_FSConverter. OTOH, nt.execve uses path_converter, which doesn't convert unicode to bytes on Windows. Thus in posixmodule.c, for the call execve(path->narrow, argvlist, envlist), path->narrow is NULL, and the CRT kills the process due to a bad argument:
(70.135c): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`7733cb70 cc int 3
0:000> bp ntdll!ZwTerminateProcess
0:000> bp desktopcrt140!execve
0:000> g
ModLoad: 000007fe`fc850000 000007fe`fc868000 C:\Windows\system32\CRYPTSP.dll
ModLoad: 000007fe`fc550000 000007fe`fc597000 C:\Windows\system32\rsaenh.dll
ModLoad: 000007fe`fceb0000 000007fe`fcebf000 C:\Windows\system32\CRYPTBASE.dll
Python 3.5.0a1 (v3.5.0a1:5d4b6a57d5fd, Feb 7 2015, 18:15:14)
[MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import nt, sys
>>> path = sys.executable
>>> nt.execve(path, ['python', '-V'], {})
Breakpoint 1 hit
DESKTOPCRT140!_execve:
000007fe`fa5ac43c 4d8bc8 mov r9,r8
0:000> r rcx
rcx=0000000000000000
The first argument is passed in AMD64 register rcx, which you can see is NULL here.
0:000> g
Breakpoint 0 hit
ntdll!NtTerminateProcess:
00000000`772e1570 4c8bd1 mov r10,rcx
0:000> k 8
Child-SP RetAddr Call Site
00000000`0038f5c8 000007fe`fd11402f ntdll!NtTerminateProcess
00000000`0038f5d0 000007fe`f54e003a KERNELBASE!TerminateProcess+0x2f
00000000`0038f600 000007fe`f54e0055 APPCRT140!_invalid_parameter+0x76
00000000`0038f640 000007fe`fa5abbd8 APPCRT140!_invalid_parameter_noinfo+0x19
00000000`0038f680 00000000`6aa116a7 DESKTOPCRT140!common_spawnv<char>+0x44
00000000`0038f6e0 00000000`6aa115a8 python35!os_execve_impl+0xb7
00000000`0038f720 00000000`6aa9ff3b python35!os_execve+0xa8
00000000`0038f7d0 00000000`6ab14aed python35!PyCFunction_Call+0xfb
Using a bytes path with nt.execve will work, but it's deprecated on Windows:
C:\>py -3.5 -Wall
Python 3.5.0a1 (v3.5.0a1:5d4b6a57d5fd, Feb 7 2015, 18:15:14)
[MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, nt, sys
>>> path = os.fsencode(sys.executable)
>>> nt.execve(path, ['python', '-V'], {})
__main__:1: DeprecationWarning: The Windows bytes API has been
deprecated, use Unicode filenames instead
C:\>Python 3.5.0a1
Since bytes paths are deprecated on Windows, these calls should be using wexecv and wexecve.
https://msdn.microsoft.com/en-us/library/431x4c1w%28v=vs.100%29.aspx
|