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

Alexandre Julliard julliard at winehq.org
Wed May 15 16:18:28 CDT 2019


Module: wine
Branch: master
Commit: 044461e8a6f4c1a29c1d72119d2ed207e9d0573b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=044461e8a6f4c1a29c1d72119d2ed207e9d0573b

Author: Martin Storsjo <martin at martin.st>
Date:   Tue May 14 22:02:50 2019 +0300

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 at martin.st>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/loader.c     | 2 +-
 dlls/ntdll/ntdll_misc.h | 7 +++++++
 dlls/ntdll/process.c    | 2 +-
 dlls/ntdll/thread.c     | 4 ++--
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 034b98c..8dae813 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3264,7 +3264,7 @@ void WINAPI RtlExitUserProcess( DWORD status )
     NtTerminateProcess( 0, status );
     LdrShutdownProcess();
     NtTerminateProcess( GetCurrentProcess(), status );
-    exit( status );
+    exit( get_unix_exit_code( status ));
 }
 
 /******************************************************************
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 24c61a0..3463ebd 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -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;
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 3ce5aeb..c1570a5 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -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;
 }
 
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index be46218..46de839 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -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();




More information about the wine-cvs mailing list