Setup signal handling and exceptions only after REQ_INIT_PROCESS_DONE

has been sent, to avoid deadlocking the debugger.
This commit is contained in:
Alexandre Julliard 2000-06-07 03:49:41 +00:00
parent 9926d33450
commit 42cc2bdf46
3 changed files with 59 additions and 71 deletions

View file

@ -734,8 +734,6 @@ BOOL SIGNAL_Init(void)
} }
#endif /* HAVE_SIGALTSTACK */ #endif /* HAVE_SIGALTSTACK */
/* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
signal( SIGPIPE, SIG_IGN );
/* automatic child reaping to avoid zombies */ /* automatic child reaping to avoid zombies */
signal( SIGCHLD, SIG_IGN ); signal( SIGCHLD, SIG_IGN );

View file

@ -11,6 +11,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@ -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 ); fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
/* try to connect to it */ /* try to connect to it */
if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strcpy( addr.sun_path, SOCKETNAME ); strcpy( addr.sun_path, SOCKETNAME );
slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1; slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
#ifdef HAVE_SOCKADDR_SUN_LEN #ifdef HAVE_SOCKADDR_SUN_LEN
addr.sun_len = slen; addr.sun_len = slen;
#endif #endif
if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
if (connect( s, (struct sockaddr *)&addr, slen ) == -1) 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) if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
fatal_error( "'%s/%s' exists,\n" fatal_error( "'%s/%s' exists,\n"
" but I cannot connect to it; maybe the server has crashed?\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 CLIENT_InitServer(void)
{ {
int fd, size; int fd, size;
const char *env_fd;
char hostname[64]; char hostname[64];
char *oldcwd, *serverdir; char *oldcwd, *serverdir;
const char *configdir; 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 */ /* retrieve the current directory */
for (size = 512; ; size *= 2) for (size = 512; ; size *= 2)
{ {
@ -497,6 +493,9 @@ int CLIENT_InitThread(void)
TEB *teb = NtCurrentTeb(); TEB *teb = NtCurrentTeb();
int fd; int fd;
/* ignore SIGPIPE so that we get a EPIPE error instead */
signal( SIGPIPE, SIG_IGN );
if (wait_reply_fd( &fd ) || (fd == -1)) if (wait_reply_fd( &fd ) || (fd == -1))
server_protocol_error( "no fd passed on first request\n" ); server_protocol_error( "no fd passed on first request\n" );
if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" ); if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" );

View file

@ -207,9 +207,6 @@ BOOL PROCESS_Init(void)
initial_envdb.hStdout = initial_startup.hStdOutput = req->hstdout; initial_envdb.hStdout = initial_startup.hStdOutput = req->hstdout;
initial_envdb.hStderr = initial_startup.hStdError = req->hstderr; 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 */ /* Remember TEB selector of initial process for emergency use */
SYSLEVEL_EmergencyTeb = NtCurrentTeb()->teb_sel; SYSLEVEL_EmergencyTeb = NtCurrentTeb()->teb_sel;
@ -318,74 +315,70 @@ static inline char *build_command_line( char **argv )
*/ */
static void start_process(void) static void start_process(void)
{ {
__TRY struct init_process_done_request *req = get_req_buffer();
{ int debugged, console_app;
struct init_process_done_request *req = get_req_buffer(); HMODULE16 hModule16;
int debugged, console_app; UINT cmdShow = SW_SHOWNORMAL;
HMODULE16 hModule16; LPTHREAD_START_ROUTINE entry;
UINT cmdShow = SW_SHOWNORMAL; PDB *pdb = PROCESS_Current();
LPTHREAD_START_ROUTINE entry; HMODULE module = pdb->exe_modref->module;
PDB *pdb = PROCESS_Current();
HMODULE module = pdb->exe_modref->module;
/* Increment EXE refcount */ /* Increment EXE refcount */
pdb->exe_modref->refCount++; pdb->exe_modref->refCount++;
/* build command line */ /* build command line */
if (!(pdb->env_db->cmd_line = build_command_line( main_exe_argv ))) goto error; if (!(pdb->env_db->cmd_line = build_command_line( main_exe_argv ))) goto error;
/* Retrieve entry point address */ /* Retrieve entry point address */
entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint ); entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint );
console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI); console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
if (console_app) pdb->flags |= PDB32_CONSOLE_PROC; if (console_app) pdb->flags |= PDB32_CONSOLE_PROC;
/* Signal the parent process to continue */ /* Signal the parent process to continue */
req->module = (void *)module; req->module = (void *)module;
req->entry = entry; req->entry = entry;
req->gui = !console_app; req->gui = !console_app;
server_call( REQ_INIT_PROCESS_DONE ); server_call( REQ_INIT_PROCESS_DONE );
debugged = req->debugged; debugged = req->debugged;
/* Load KERNEL (necessary for TASK_Create) */ /* Install signal handlers; this cannot be done before, since we cannot
if (!LoadLibraryA( "KERNEL32" )) goto error; * send exceptions to the debugger before the create process event that
* is sent by REQ_INIT_PROCESS_DONE */
if (!SIGNAL_Init()) goto error;
/* Create 16-bit dummy module */ /* Load KERNEL (necessary for TASK_Create) */
if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32) if (!LoadLibraryA( "KERNEL32" )) goto error;
ExitProcess( hModule16 );
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW) /* Create 16-bit dummy module */
cmdShow = pdb->env_db->startup_info->wShowWindow; if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32)
if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow, ExitProcess( hModule16 );
NtCurrentTeb(), NULL, 0 ))
goto error;
/* Load the system dlls */ if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
if (!load_system_dlls()) goto error; cmdShow = pdb->env_db->startup_info->wShowWindow;
if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow,
NtCurrentTeb(), NULL, 0 ))
goto error;
EnterCriticalSection( &pdb->crit_section ); /* Load the system dlls */
PE_InitTls(); if (!load_system_dlls()) goto error;
MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
LeaveCriticalSection( &pdb->crit_section );
/* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */ EnterCriticalSection( &pdb->crit_section );
if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 ); PE_InitTls();
MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
LeaveCriticalSection( &pdb->crit_section );
TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry ); /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
if (debugged) DbgBreakPoint(); if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
/* FIXME: should use _PEB as parameter for NT 3.5 programs !
* Dunno about other OSs */
ExitThread( entry(NULL) );
error: TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
ExitProcess( GetLastError() ); if (debugged) DbgBreakPoint();
/* FIXME: should use _PEB as parameter for NT 3.5 programs !
* Dunno about other OSs */
ExitThread( entry(NULL) );
} error:
__EXCEPT(UnhandledExceptionFilter) ExitProcess( GetLastError() );
{
TerminateThread( GetCurrentThread(), GetExceptionCode() );
}
__ENDTRY
} }
@ -410,8 +403,6 @@ static void PROCESS_Start( HMODULE main_module, LPCSTR filename )
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE )) PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
ExitProcess( GetLastError() ); ExitProcess( GetLastError() );
SIGNAL_Init(); /* reinitialize signal stack */
/* switch to the new stack */ /* switch to the new stack */
SYSDEPS_SwitchToThreadStack( start_process ); SYSDEPS_SwitchToThreadStack( start_process );
} }