ntdll: Avoid truncating a nonzero exit code to zero in unix.

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>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Martin Storsjo 2019-05-14 22:02:50 +03:00 committed by Alexandre Julliard
parent 4872747b27
commit 044461e8a6
4 changed files with 11 additions and 4 deletions

View File

@ -3264,7 +3264,7 @@ void WINAPI RtlExitUserProcess( DWORD status )
NtTerminateProcess( 0, status );
LdrShutdownProcess();
NtTerminateProcess( GetCurrentProcess(), status );
exit( status );
exit( get_unix_exit_code( status ));
}
/******************************************************************

View File

@ -247,6 +247,13 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
return (struct ntdll_thread_data *)&NtCurrentTeb()->GdiTebBatch;
}
static inline int get_unix_exit_code( NTSTATUS status )
{
/* prevent a nonzero exit code to end up truncated to zero in unix */
if (status && !(status & 0xff)) return 1;
return status;
}
extern mode_t FILE_umask DECLSPEC_HIDDEN;
extern HANDLE keyed_event DECLSPEC_HIDDEN;
extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN;

View File

@ -88,7 +88,7 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
self = !ret && reply->self;
}
SERVER_END_REQ;
if (self && handle) _exit( exit_code );
if (self && handle) _exit( get_unix_exit_code( exit_code ));
return ret;
}

View File

@ -291,7 +291,7 @@ 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) _exit( get_unix_exit_code( status ));
signal_exit_thread( status );
}
@ -332,7 +332,7 @@ void WINAPI RtlExitUserThread( ULONG status )
{
LdrShutdownProcess();
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
signal_exit_process( status );
signal_exit_process( get_unix_exit_code( status ));
}
LdrShutdownThread();