On 13.05.19 12:30, Martin Storsjo wrote:
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
This is an alternative to https://source.winehq.org/patches/data/164482 (fixing the same issue in winedbg), by keeping the full range of the winedbg exit code and just avoiding the issue right before calling exit/_exit.
dlls/ntdll/loader.c | 3 +++ dlls/ntdll/process.c | 7 ++++++- dlls/ntdll/signal_arm.c | 3 +++ dlls/ntdll/signal_arm64.c | 3 +++ dlls/ntdll/signal_i386.c | 3 +++ dlls/ntdll/signal_powerpc.c | 3 +++ dlls/ntdll/signal_x86_64.c | 3 +++ dlls/ntdll/thread.c | 7 ++++++- 8 files changed, 30 insertions(+), 2 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/signal_arm.c b/dlls/ntdll/signal_arm.c index e01c8ce219..4f4dcced05 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -1396,6 +1396,9 @@ void signal_exit_thread( int status ) */ void signal_exit_process( int status ) {
- /* Prevent a nonzero exit code to end up truncated to zero in unix. */
- if (status != 0 && (status & 0xff) == 0)
}status = 1; call_thread_exit_func( status, exit, NtCurrentTeb() );
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 8114d45fef..e56dd6b1ab 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -1171,6 +1171,9 @@ void signal_exit_thread( int status ) */ void signal_exit_process( int 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/signal_i386.c b/dlls/ntdll/signal_i386.c index 053c87da83..a89ff20fd6 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2817,6 +2817,9 @@ void signal_exit_thread( int status ) */ void signal_exit_process( int status ) {
- /* Prevent a nonzero exit code to end up truncated to zero in unix. */
- if (status != 0 && (status & 0xff) == 0)
}status = 1; call_thread_exit_func( status, exit );
diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 86398d8f54..a5cce9bae3 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -1240,6 +1240,9 @@ void signal_exit_thread( int status ) */ void signal_exit_process( int 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/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 21e7098876..140e11b491 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -4603,6 +4603,9 @@ void signal_exit_thread( int status ) */ void signal_exit_process( int status ) {
- /* Prevent a nonzero exit code to end up truncated to zero in unix. */
- if (status != 0 && (status & 0xff) == 0)
}status = 1; call_thread_exit_func( status, exit );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index be4621819b..66a92eb3fc 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 ); }
Signed-off-by: André Hentschel nerv@dawncrow.de