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