From 42cc2bdf46e276c79f9670dc2cd83d65acedeee7 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 7 Jun 2000 03:49:41 +0000 Subject: [PATCH] Setup signal handling and exceptions only after REQ_INIT_PROCESS_DONE has been sent, to avoid deadlocking the debugger. --- dlls/ntdll/signal_i386.c | 2 - scheduler/client.c | 19 ++++--- scheduler/process.c | 125 ++++++++++++++++++++++------------------------- 3 files changed, 67 insertions(+), 79 deletions(-) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 24818b8773e..f1d89105ace 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -734,8 +734,6 @@ BOOL SIGNAL_Init(void) } #endif /* HAVE_SIGALTSTACK */ - /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */ - signal( SIGPIPE, SIG_IGN ); /* automatic child reaping to avoid zombies */ signal( SIGCHLD, SIG_IGN ); diff --git a/scheduler/client.c b/scheduler/client.c index ffb33fcb645..324aaf74242 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -411,16 +412,19 @@ static int server_connect( const char *oldcwd, const char *serverdir ) fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME ); /* try to connect to it */ - if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" ); addr.sun_family = AF_UNIX; strcpy( addr.sun_path, SOCKETNAME ); slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1; #ifdef HAVE_SOCKADDR_SUN_LEN addr.sun_len = slen; #endif + if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" ); if (connect( s, (struct sockaddr *)&addr, slen ) == -1) { - usleep( 50000 ); /* in case the server was starting right now */ + close( s ); + /* wait a bit and retry with a new socket */ + usleep( 50000 ); + if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" ); if (connect( s, (struct sockaddr *)&addr, slen ) == -1) fatal_error( "'%s/%s' exists,\n" " but I cannot connect to it; maybe the server has crashed?\n" @@ -440,18 +444,10 @@ static int server_connect( const char *oldcwd, const char *serverdir ) int CLIENT_InitServer(void) { int fd, size; - const char *env_fd; char hostname[64]; char *oldcwd, *serverdir; const char *configdir; - /* first check if we inherited the socket fd */ - if ((env_fd = getenv( "__WINE_FD" )) && isdigit(env_fd[0])) - { - fd = atoi( env_fd ); - if (fcntl( fd, F_SETFD, 1 ) != -1) return fd; /* set close on exec flag */ - } - /* retrieve the current directory */ for (size = 512; ; size *= 2) { @@ -497,6 +493,9 @@ int CLIENT_InitThread(void) TEB *teb = NtCurrentTeb(); int fd; + /* ignore SIGPIPE so that we get a EPIPE error instead */ + signal( SIGPIPE, SIG_IGN ); + if (wait_reply_fd( &fd ) || (fd == -1)) server_protocol_error( "no fd passed on first request\n" ); if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" ); diff --git a/scheduler/process.c b/scheduler/process.c index 861c0440e02..1c8205a78fb 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -207,9 +207,6 @@ BOOL PROCESS_Init(void) initial_envdb.hStdout = initial_startup.hStdOutput = req->hstdout; initial_envdb.hStderr = initial_startup.hStdError = req->hstderr; - /* Initialize signal handling */ - if (!SIGNAL_Init()) return FALSE; - /* Remember TEB selector of initial process for emergency use */ SYSLEVEL_EmergencyTeb = NtCurrentTeb()->teb_sel; @@ -318,74 +315,70 @@ static inline char *build_command_line( char **argv ) */ static void start_process(void) { - __TRY - { - struct init_process_done_request *req = get_req_buffer(); - int debugged, console_app; - HMODULE16 hModule16; - UINT cmdShow = SW_SHOWNORMAL; - LPTHREAD_START_ROUTINE entry; - PDB *pdb = PROCESS_Current(); - HMODULE module = pdb->exe_modref->module; - - /* Increment EXE refcount */ - pdb->exe_modref->refCount++; - - /* build command line */ - if (!(pdb->env_db->cmd_line = build_command_line( main_exe_argv ))) goto error; - - /* Retrieve entry point address */ - entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint ); - console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); - - if (console_app) pdb->flags |= PDB32_CONSOLE_PROC; - - /* Signal the parent process to continue */ - req->module = (void *)module; - req->entry = entry; - req->gui = !console_app; - server_call( REQ_INIT_PROCESS_DONE ); - debugged = req->debugged; - - /* Load KERNEL (necessary for TASK_Create) */ - if (!LoadLibraryA( "KERNEL32" )) goto error; - - /* Create 16-bit dummy module */ - if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32) - ExitProcess( hModule16 ); - - if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW) - cmdShow = pdb->env_db->startup_info->wShowWindow; - if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow, - NtCurrentTeb(), NULL, 0 )) - goto error; + struct init_process_done_request *req = get_req_buffer(); + int debugged, console_app; + HMODULE16 hModule16; + UINT cmdShow = SW_SHOWNORMAL; + LPTHREAD_START_ROUTINE entry; + PDB *pdb = PROCESS_Current(); + HMODULE module = pdb->exe_modref->module; - /* Load the system dlls */ - if (!load_system_dlls()) goto error; + /* Increment EXE refcount */ + pdb->exe_modref->refCount++; - EnterCriticalSection( &pdb->crit_section ); - PE_InitTls(); - MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 ); - LeaveCriticalSection( &pdb->crit_section ); + /* build command line */ + if (!(pdb->env_db->cmd_line = build_command_line( main_exe_argv ))) goto error; - /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */ - if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 ); + /* Retrieve entry point address */ + entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint ); + console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); - TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry ); - if (debugged) DbgBreakPoint(); - /* FIXME: should use _PEB as parameter for NT 3.5 programs ! - * Dunno about other OSs */ - ExitThread( entry(NULL) ); + if (console_app) pdb->flags |= PDB32_CONSOLE_PROC; - error: - ExitProcess( GetLastError() ); + /* Signal the parent process to continue */ + req->module = (void *)module; + req->entry = entry; + req->gui = !console_app; + server_call( REQ_INIT_PROCESS_DONE ); + debugged = req->debugged; - } - __EXCEPT(UnhandledExceptionFilter) - { - TerminateThread( GetCurrentThread(), GetExceptionCode() ); - } - __ENDTRY + /* 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 */ + if (!SIGNAL_Init()) goto error; + + /* Load KERNEL (necessary for TASK_Create) */ + if (!LoadLibraryA( "KERNEL32" )) goto error; + + /* Create 16-bit dummy module */ + if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32) + ExitProcess( hModule16 ); + + if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW) + cmdShow = pdb->env_db->startup_info->wShowWindow; + if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow, + NtCurrentTeb(), NULL, 0 )) + goto error; + + /* Load the system dlls */ + if (!load_system_dlls()) goto error; + + EnterCriticalSection( &pdb->crit_section ); + PE_InitTls(); + MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 ); + LeaveCriticalSection( &pdb->crit_section ); + + /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */ + if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 ); + + TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry ); + if (debugged) DbgBreakPoint(); + /* FIXME: should use _PEB as parameter for NT 3.5 programs ! + * Dunno about other OSs */ + ExitThread( entry(NULL) ); + + error: + ExitProcess( GetLastError() ); } @@ -410,8 +403,6 @@ static void PROCESS_Start( HMODULE main_module, LPCSTR filename ) PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE )) ExitProcess( GetLastError() ); - SIGNAL_Init(); /* reinitialize signal stack */ - /* switch to the new stack */ SYSDEPS_SwitchToThreadStack( start_process ); } -- 2.11.4.GIT