Alexandre Julliard : ntdll: Block async signals during process init and thread creation.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jan 18 06:45:15 CST 2007


Module: wine
Branch: master
Commit: 8891d6de48fdc43ef045fcc7470297952a97ed92
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8891d6de48fdc43ef045fcc7470297952a97ed92

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jan 18 12:23:04 2007 +0100

ntdll: Block async signals during process init and thread creation.

---

 dlls/ntdll/loader.c     |   19 +------------------
 dlls/ntdll/ntdll_misc.h |    1 +
 dlls/ntdll/server.c     |   33 +++++++++++++++++++++++++++++++++
 dlls/ntdll/thread.c     |   13 ++++++++++++-
 4 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3e3bc05..7ff3ca1 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2139,24 +2139,7 @@ void WINAPI LdrInitializeThunk( ULONG un
     RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
     InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList );
 
-    /* Install signal handlers; this cannot be done before, since we cannot
-     * send exceptions to the debugger before the create process event that
-     * is sent by REQ_INIT_PROCESS_DONE.
-     * We do need the handlers in place by the time the request is over, so
-     * we set them up here. If we segfault between here and the server call
-     * something is very wrong... */
-    if (!SIGNAL_Init()) exit(1);
-
-    /* Signal the parent process to continue */
-    SERVER_START_REQ( init_process_done )
-    {
-        req->module = peb->ImageBaseAddress;
-        req->entry  = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
-        req->gui    = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
-        status = wine_server_call( req );
-    }
-    SERVER_END_REQ;
-
+    status = server_init_process_done();
     if (status != STATUS_SUCCESS) goto error;
 
     RtlEnterCriticalSection( &loader_section );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 725665d..4a8c474 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -58,6 +58,7 @@ extern void virtual_init_threading(void)
 /* server support */
 extern abs_time_t server_start_time;
 extern void server_init_process(void);
+extern NTSTATUS server_init_process_done(void);
 extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point );
 extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
 extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index ded9f5b..ce0c3af 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -1018,6 +1018,7 @@ void server_init_process(void)
     sigaddset( &server_block_set, SIGUSR1 );
     sigaddset( &server_block_set, SIGUSR2 );
     sigaddset( &server_block_set, SIGCHLD );
+    pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
 
     /* receive the first thread request fd on the main socket */
     ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle );
@@ -1029,6 +1030,38 @@ void server_init_process(void)
 
 
 /***********************************************************************
+ *           server_init_process_done
+ */
+NTSTATUS server_init_process_done(void)
+{
+    PEB *peb = NtCurrentTeb()->Peb;
+    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
+    NTSTATUS status;
+
+    /* Install signal handlers; this cannot be done earlier, since we cannot
+     * send exceptions to the debugger before the create process event that
+     * is sent by REQ_INIT_PROCESS_DONE.
+     * We do need the handlers in place by the time the request is over, so
+     * we set them up here. If we segfault between here and the server call
+     * something is very wrong... */
+    if (!SIGNAL_Init()) exit(1);
+
+    /* Signal the parent process to continue */
+    SERVER_START_REQ( init_process_done )
+    {
+        req->module = peb->ImageBaseAddress;
+        req->entry  = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
+        req->gui    = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
+        status = wine_server_call( req );
+    }
+    SERVER_END_REQ;
+
+    pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
+    return status;
+}
+
+
+/***********************************************************************
  *           server_init_thread
  *
  * Send an init thread request. Return 0 if OK.
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 4a82e43..356ba11 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -346,6 +346,8 @@ static void start_thread( struct wine_pt
     size = page_size;
     NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL );
 
+    pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
+
     RtlAcquirePebLock();
     InsertHeadList( &tls_links, &teb->TlsLinks );
     RtlReleasePebLock();
@@ -380,6 +382,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
                                      PRTL_THREAD_START_ROUTINE start, void *param,
                                      HANDLE *handle_ptr, CLIENT_ID *id )
 {
+    sigset_t sigset;
     struct ntdll_thread_data *thread_data;
     struct ntdll_thread_regs *thread_regs = NULL;
     struct startup_info *info = NULL;
@@ -416,7 +419,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
     }
     SERVER_END_REQ;
 
-    if (status) goto error;
+    if (status)
+    {
+        close( request_pipe[1] );
+        return status;
+    }
+
+    pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, &sigset );
 
     addr = NULL;
     size = sigstack_total_size;
@@ -469,6 +478,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
         status = STATUS_NO_MEMORY;
         goto error;
     }
+    pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
 
     if (id) id->UniqueThread = (HANDLE)tid;
     if (handle_ptr) *handle_ptr = handle;
@@ -484,6 +494,7 @@ error:
         NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
     }
     if (handle) NtClose( handle );
+    pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
     close( request_pipe[1] );
     return status;
 }




More information about the wine-cvs mailing list