Delay sending debug events until process initialization is complete.
diff --git a/include/module.h b/include/module.h
index 9383816..7790d4f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -157,6 +157,7 @@
#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
+#define WINE_MODREF_DEBUG_EVENT_SENT 0x00000040
#define WINE_MODREF_MARKER 0x80000000
@@ -181,6 +182,7 @@
extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved );
extern void MODULE_DllThreadAttach( LPVOID lpReserved );
extern void MODULE_DllThreadDetach( LPVOID lpReserved );
+extern void MODULE_SendLoadDLLEvents( void );
extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
diff --git a/loader/module.c b/loader/module.c
index 9441e03..7db93e1 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -327,6 +327,29 @@
return retval;
}
+/*************************************************************************
+ * MODULE_SendLoadDLLEvents
+ *
+ * Sends DEBUG_DLL_LOAD events for all outstanding modules.
+ *
+ * NOTE: Assumes that the process critical section is held!
+ *
+ */
+void MODULE_SendLoadDLLEvents( void )
+{
+ WINE_MODREF *wm;
+
+ for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
+ {
+ if ( wm->type != MODULE32_PE ) continue;
+ if ( wm == PROCESS_Current()->exe_modref ) continue;
+ if ( wm->flags & WINE_MODREF_DEBUG_EVENT_SENT ) continue;
+
+ DEBUG_SendLoadDLLEvent( -1 /*FIXME*/, wm->module, &wm->modname );
+ wm->flags |= WINE_MODREF_DEBUG_EVENT_SENT;
+ }
+}
+
/***********************************************************************
* MODULE_CreateDummyModule
@@ -1321,13 +1344,18 @@
EnterCriticalSection(&PROCESS_Current()->crit_section);
wm = MODULE_LoadLibraryExA( libname, hfile, flags );
-
- if(wm && !MODULE_DllProcessAttach(wm, NULL))
+ if ( wm )
{
- WARN_(module)("Attach failed for module '%s', \n", libname);
- MODULE_FreeLibrary(wm);
- SetLastError(ERROR_DLL_INIT_FAILED);
- wm = NULL;
+ if ( PROCESS_Current()->flags & PDB32_DEBUGGED )
+ MODULE_SendLoadDLLEvents();
+
+ if ( !MODULE_DllProcessAttach( wm, NULL ) )
+ {
+ WARN_(module)("Attach failed for module '%s', \n", libname);
+ MODULE_FreeLibrary(wm);
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ wm = NULL;
+ }
}
LeaveCriticalSection(&PROCESS_Current()->crit_section);
@@ -1411,9 +1439,6 @@
LeaveCriticalSection(&PROCESS_Current()->crit_section);
- if (PROCESS_Current()->flags & PDB32_DEBUGGED)
- DEBUG_SendLoadDLLEvent( -1 /*FIXME*/, pwm->module, &pwm->modname );
-
return pwm;
}
diff --git a/scheduler/process.c b/scheduler/process.c
index a65be8e..6dde795 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -409,10 +409,33 @@
if (!TASK_Create( pModule, cmdShow ))
goto error;
- /* Perform Win16 specific process initialization */
- if ( type == PROC_WIN16 )
+ /* Load all process modules */
+ switch ( type )
+ {
+ case PROC_WIN16:
if ( !NE_InitProcess( pModule ) )
goto error;
+ break;
+
+ case PROC_WIN32:
+ /* Create 32-bit MODREF */
+ if ( !PE_CreateModule( pModule->module32, filename, 0, FALSE ) )
+ goto error;
+
+ /* Increment EXE refcount */
+ assert( pdb->exe_modref );
+ pdb->exe_modref->refCount++;
+
+ /* Retrieve entry point address */
+ entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32,
+ OptionalHeader.AddressOfEntryPoint);
+ break;
+
+ case PROC_DOS:
+ /* FIXME: move DOS startup code here */
+ break;
+ }
+
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
* context of the parent process. Actually, the USER signal proc
@@ -426,39 +449,33 @@
PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0, 0 );
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, GetCurrentThreadId(), 0 );
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0, 0 );
+ PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0, 0 );
/* Signal the parent process to continue */
server_call( REQ_INIT_PROCESS_DONE );
- /* Perform Win32 specific process initialization */
- if ( type == PROC_WIN32 )
+ /* Send all required start-up debugger events */
+ if ( type == PROC_WIN32 && (pdb->flags & PDB32_DEBUGGED) )
{
- /* Send the debug event to the debugger */
- entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32,
- OptionalHeader.AddressOfEntryPoint);
- if (pdb->flags & PDB32_DEBUGGED)
- DEBUG_SendCreateProcessEvent( -1 /*FIXME*/, pModule->module32, entry );
+ EnterCriticalSection( &pdb->crit_section );
- /* Create 32-bit MODREF */
- if (!PE_CreateModule( pModule->module32, filename, 0, FALSE )) goto error;
+ DEBUG_SendCreateProcessEvent( -1 /*FIXME*/, pModule->module32, entry );
+ MODULE_SendLoadDLLEvents();
- /* Increment EXE refcount */
- assert( pdb->exe_modref );
- pdb->exe_modref->refCount++;
-
- /* Initialize thread-local storage */
- PE_InitTls();
+ LeaveCriticalSection( &pdb->crit_section );
}
- PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0, 0 ); /* FIXME: correct location? */
-
if ( (pdb->flags & PDB32_CONSOLE_PROC) || (pdb->flags & PDB32_DOS_PROC) )
AllocConsole();
+ /* Perform Win32 specific process initialization */
if ( type == PROC_WIN32 )
{
EnterCriticalSection( &pdb->crit_section );
+
+ PE_InitTls();
MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
+
LeaveCriticalSection( &pdb->crit_section );
}