On Windows, the exit codes can use the full 32 bit range, while on unix, they are truncated to the lowest 8 bits. If the intended exit code is nonzero, to indicate failure, but the lower 8 bits are zero (like when winedbg tries to exit with EXCEPTION_WINE_STUB, 80000100), the observed exit code used to be zero, indicating successful execution.
Signed-off-by: Martin Storsjo martin@martin.st --- Moved fixing up of the return code to the caller of signal_exit_process. --- dlls/ntdll/loader.c | 3 +++ dlls/ntdll/process.c | 7 ++++++- dlls/ntdll/thread.c | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 994ff6f215..0279c81aa7 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3264,6 +3264,9 @@ void WINAPI RtlExitUserProcess( DWORD status ) NtTerminateProcess( 0, status ); LdrShutdownProcess(); NtTerminateProcess( GetCurrentProcess(), status ); + /* Prevent a nonzero exit code to end up truncated to zero in unix. */ + if (status != 0 && (status & 0xff) == 0) + status = 1; exit( status ); }
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 573a7a771d..ea3565cb1c 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -88,7 +88,12 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code ) self = !ret && reply->self; } SERVER_END_REQ; - if (self && handle) _exit( exit_code ); + if (self && handle) { + /* Prevent a nonzero exit code to end up truncated to zero in unix. */ + if (exit_code != 0 && (exit_code & 0xff) == 0) + exit_code = 1; + _exit( exit_code ); + } return ret; }
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index be4621819b..b17ddda7b6 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -291,7 +291,12 @@ static void free_thread_data( TEB *teb ) void abort_thread( int status ) { pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); - if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status ); + if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) { + /* Prevent a nonzero exit code to end up truncated to zero in unix. */ + if (status != 0 && (status & 0xff) == 0) + status = 1; + _exit( status ); + } signal_exit_thread( status ); }
@@ -316,6 +321,7 @@ void WINAPI RtlExitUserThread( ULONG status ) { static void *prev_teb; TEB *teb; + int exit_code;
if (status) /* send the exit code to the server (0 is already the default) */ { @@ -332,7 +338,11 @@ void WINAPI RtlExitUserThread( ULONG status ) { LdrShutdownProcess(); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); - signal_exit_process( status ); + exit_code = status; + /* Prevent a nonzero exit code to end up truncated to zero in unix. */ + if (status != 0 && (status & 0xff) == 0) + exit_code = 1; + signal_exit_process( exit_code ); }
LdrShutdownThread();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52223
Your paranoid android.
=== debian9 (32 bit WoW report) ===
ntdll: om.c:2116: Test failed: got 99
On Tue, 14 May 2019, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=52223
Your paranoid android.
=== debian9 (32 bit WoW report) ===
ntdll: om.c:2116: Test failed: got 99
This doesn't look like it's related to this patch.
// Martin