| msg151304 - (view) |
Author: Kay Hayen (kayhayen) |
Date: 2012-01-15 23:05 |
| Hello, I am the author of the Python compiler Nuitka. It has the ability to immediately execute the created executable file. For that I am using "os.execl" to immediately replace the compiler and run the freshly created binary instead. This worked well so far, but as of late, I am also checking the exit codes, and it turns out that even for failing programs, the exit code is "0" on Windows, even though the compiled binary is exiting with "1". Investigating further, I made a simple program: ------- import os os.execl( "FailingProgram.exe", "lala" ) ------- And it turns out, it's giving me "0", whereas when executed directly "FailingProgram.exe" gives "1". Checking %errorlevel% manually that is, my test framework uses "subprocess" module and gets "0". The same code works fine (preserves exit code) under Linux. I didn't find the windows specific code responsible for implementing "os.execv" under Win32. I am suspecting that somehow "cmd.exe" may not be propagating the error code, but for that to confirm I would need pointers. Thanks in advance, Kay |
|
|
| msg151305 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2012-01-15 23:13 |
| Python's os.execl simply calls Windows' execv() function, which AFAIK has nothing to do with cmd.exe. |
|
|
| msg151325 - (view) |
Author: Kay Hayen (kayhayen) |
Date: 2012-01-16 06:08 |
| Well, I saw that code, but expected that there must be more to it. But I found out, the bug is actually caused by at least MinGW. See below how I build a program with it, that does "execl" on an error exiting program and then the "errorlevel" variable is "0", whereas direct execution gives "1". I don't have MSVC installed, so I cannot tell if it is affected as well. I will report this as a bug to MinGW then. c:\Users\hayen\Nuitka>gcc -v Es werden eingebaute Spezifikationen verwendet. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=c:/mingw/lib/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe Ziel: mingw32 Konfiguriert mit: ../gcc-4.6.2/configure --enable-languages=c,c++,ada,fortran,ob jc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libg omp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific- runtime-libs --build=mingw32 --prefix=/mingw Thread-Modell: win32 gcc-Version 4.6.2 (GCC) c:\Users\hayen\Nuitka>gcc exec_sample.cpp c:\Users\hayen\Nuitka>type exec_sample.cpp #include <unistd.h> #include <stdio.h> int main() { puts( "Hello bad world!" ); execl( "badprogram.exe", "badprogram", "what" ); puts( "Look, this is not happening!" ); return 2; } c:\Users\hayen\Nuitka>.\a.exe Hello bad world! c:\Users\hayen\Nuitka>Traceback (most recent call last): File "tests\syntax\RelativeNonPackageImport.py", line 20, in from . import whatever ValueError: Attempted relative import in non-package c:\Users\hayen\Nuitka>echo %errorlevel% 0 c:\Users\hayen\Nuitka>.\badprogram.exe Traceback (most recent call last): File "tests\syntax\RelativeNonPackageImport.py", line 20, in from . import whatever ValueError: Attempted relative import in non-package c:\Users\hayen\Nuitka>echo %errorlevel% 1 |
|
|
| msg151430 - (view) |
Author: Amaury Forgeot d'Arc (Amaury.Forgeot.d'Arc) * |
Date: 2012-01-17 07:26 |
| immediately execute the created executable file. For that I am using "os.execl" to immediately replace the compiler and run the freshly created binary instead. > > This worked well so far, but as of late, I am also checking the exit codes, and it turns out that even for failing programs, the exit code is "0" on Windows, even though the compiled binary is exiting with "1". This is expected behavior on Windows: exec does not replace the existing process like with Unix, it creates a new process and exit(0) the caller. |
|
|
| msg151434 - (view) |
Author: Kay Hayen (kayhayen) |
Date: 2012-01-17 09:28 |
| Does the Python standard library not offer anything that does replace with current process code with another? I checked with subprocess, and admittedly it's not that. Does Win32 API offer nothing for that? |
|
|
| msg151438 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) *  |
Date: 2012-01-17 10:04 |
| No. On Windows the only way to start a new executable is to create a new process (with the CreateProcess function, which all spawn* and exec* functions ultimately call), and this yields a new PID. This is a fundamental difference with unix, where the only way to create a process is to clone the current one with fork(). And yes, this makes launchers more difficult to write on Windows. For a discussion see the paragraph "Process Launching" in http://www.python.org/dev/peps/pep-0397/ |
|
|
| msg164360 - (view) |
Author: Tim Golden (tim.golden) *  |
Date: 2012-06-29 22:07 |
| Closing as it's been pending for six months and I see nothing further to add |
|
|