diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 1d54de1cad7..037947a5f82 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -8,6 +8,7 @@ #include "debugtools.h" #include "winnt.h" #include "ntddk.h" +#include "process.h" #include "wine/exception.h" #include "stackframe.h" @@ -69,7 +70,8 @@ static DWORD EXC_CallHandler( PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nes newframe.frame.Handler = nested_handler; newframe.prevFrame = frame; EXC_push_frame( &newframe.frame ); - TRACE( "calling handler at %p\n", handler ); + TRACE( "calling handler at %p code=%lx flags=%lx\n", + handler, record->ExceptionCode, record->ExceptionFlags ); ret = handler( record, frame, context, dispatcher ); TRACE( "handler returned %lx\n", ret ); EXC_pop_frame( &newframe.frame ); @@ -84,6 +86,10 @@ static DWORD EXC_CallHandler( PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nes */ static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) { + if ((PROCESS_Current()->flags & PDB32_DEBUGGED) && + (DEBUG_SendExceptionEvent( rec, FALSE ) == DBG_CONTINUE)) + return; /* continue execution */ + if (rec->ExceptionFlags & EH_STACK_INVALID) ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); else if (rec->ExceptionCode == EXCEPTION_NONCONTINUABLE_EXCEPTION) @@ -105,6 +111,12 @@ void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *contex EXCEPTION_RECORD newrec; DWORD res; + TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags ); + + if ((PROCESS_Current()->flags & PDB32_DEBUGGED) && + (DEBUG_SendExceptionEvent( rec, TRUE ) == DBG_CONTINUE)) + return; /* continue execution */ + frame = NtCurrentTeb()->except; nested_frame = NULL; while (frame != (PEXCEPTION_FRAME)0xFFFFFFFF) @@ -181,7 +193,9 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, } pRecord->ExceptionFlags |= EH_UNWINDING | (pEndFrame ? 0 : EH_EXIT_UNWIND); - + + TRACE( "code=%lx flags=%lx\n", pRecord->ExceptionCode, pRecord->ExceptionFlags ); + /* get chain of exception frames */ frame = NtCurrentTeb()->except; while ((frame != (PEXCEPTION_FRAME)0xffffffff) && (frame != pEndFrame)) diff --git a/include/dosexe.h b/include/dosexe.h index 5e86bae8c27..666c5005442 100644 --- a/include/dosexe.h +++ b/include/dosexe.h @@ -65,7 +65,7 @@ extern LPDOSTASK MZ_AllocDPMITask( HMODULE16 hModule ); extern BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); extern LPDOSTASK MZ_Current( void ); extern int DOSVM_Enter( PCONTEXT context ); diff --git a/include/module.h b/include/module.h index f5a9f68c60e..3a49ecee389 100644 --- a/include/module.h +++ b/include/module.h @@ -204,7 +204,7 @@ extern HANDLE NE_OpenFile( NE_MODULE *pModule ); extern HINSTANCE16 MODULE_LoadModule16( LPCSTR name, BOOL implicit ); extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); /* loader/ne/resource.c */ diff --git a/include/pe_image.h b/include/pe_image.h index 94396582d85..f213a376598 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -33,7 +33,7 @@ extern struct _wine_modref *PE_CreateModule( HMODULE hModule, OFSTRUCT *ofs, DWORD flags, BOOL builtin ); extern BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); extern void PE_InitTls(void); diff --git a/include/process.h b/include/process.h index b7486dc4735..64969ce78cf 100644 --- a/include/process.h +++ b/include/process.h @@ -160,9 +160,15 @@ extern PDB *PROCESS_Create( struct _NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, + BOOL inherit, DWORD flags, STARTUPINFOA *startup, PROCESS_INFORMATION *info ); extern void PROCESS_FreePDB( PDB *pdb ); -#endif /* __WINE_PROCESS_H */ +/* scheduler/debugger.c */ +extern DWORD DEBUG_SendExceptionEvent( EXCEPTION_RECORD *rec, BOOL first_chance ); +extern DWORD DEBUG_SendCreateProcessEvent( HFILE file, HMODULE module, void *entry ); +extern DWORD DEBUG_SendCreateThreadEvent( void *entry ); +extern DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR name ); +extern DWORD DEBUG_SendUnloadDLLEvent( HMODULE module ); +#endif /* __WINE_PROCESS_H */ diff --git a/include/thread.h b/include/thread.h index 66d5e50d715..4426e022184 100644 --- a/include/thread.h +++ b/include/thread.h @@ -57,7 +57,7 @@ typedef struct _THDB void *ring0_thread; /* 5c Pointer to ring 0 thread */ void *ptdbx; /* 60 Pointer to TDBX structure */ void *stack_base; /* 64 Base of the stack */ - void *exit_stack; /* 68 Stack pointer on thread exit */ + void *signal_stack; /* 68 Signal stack (was: exit_stack) */ void *emu_data; /* 6c Related to 80387 emulation */ DWORD last_error; /* 70 Last error code */ void *debugger_CB; /* 74 Debugger context block */ @@ -93,6 +93,9 @@ typedef struct _THDB /* The pseudo handle value returned by GetCurrentThread */ #define CURRENT_THREAD_PSEUDOHANDLE 0xfffffffe +/* The per-thread signal stack size */ +#define SIGNAL_STACK_SIZE 16384 + #ifdef __i386__ /* On the i386, the current thread is in the %fs register */ # define SET_CUR_THREAD(thdb) SET_FS((thdb)->teb_sel) diff --git a/loader/dos/module.c b/loader/dos/module.c index b67da36f79f..040472c181c 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -452,7 +452,7 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) { LPDOSTASK lpDosTask = NULL; /* keep gcc from complaining */ @@ -501,7 +501,7 @@ BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env, } inherit = TRUE; /* bad hack for inheriting the CreatePipe... */ if (!PROCESS_Create( pModule, cmdline, env, 0, 0, - psa, tsa, inherit, startup, info )) + psa, tsa, inherit, flags, startup, info )) return FALSE; } return TRUE; diff --git a/loader/module.c b/loader/module.c index 618ec5eb433..0c4cdb204e2 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1069,10 +1069,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, /* Warn if unsupported features are used */ - if (dwCreationFlags & DEBUG_PROCESS) - FIXME_(module)("(%s,...): DEBUG_PROCESS ignored\n", name); - if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS) - FIXME_(module)("(%s,...): DEBUG_ONLY_THIS_PROCESS ignored\n", name); if (dwCreationFlags & CREATE_SUSPENDED) FIXME_(module)("(%s,...): CREATE_SUSPENDED ignored\n", name); if (dwCreationFlags & DETACHED_PROCESS) @@ -1141,7 +1137,8 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, lstrcpynA( ofs.szPathName, name, sizeof( ofs.szPathName ) ); retv = NE_CreateProcess( HFILE_ERROR, &ofs, cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, - bInheritHandles, lpStartupInfo, lpProcessInfo ); + bInheritHandles, dwCreationFlags, + lpStartupInfo, lpProcessInfo ); /* Load file and create process */ @@ -1176,19 +1173,22 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, case SCS_32BIT_BINARY: retv = PE_CreateProcess( hFile, &ofs, cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, - bInheritHandles, lpStartupInfo, lpProcessInfo ); + bInheritHandles, dwCreationFlags, + lpStartupInfo, lpProcessInfo ); break; case SCS_DOS_BINARY: retv = MZ_CreateProcess( hFile, &ofs, cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, - bInheritHandles, lpStartupInfo, lpProcessInfo ); + bInheritHandles, dwCreationFlags, + lpStartupInfo, lpProcessInfo ); break; case SCS_WOW_BINARY: retv = NE_CreateProcess( hFile, &ofs, cmdline, lpEnvironment, lpProcessAttributes, lpThreadAttributes, - bInheritHandles, lpStartupInfo, lpProcessInfo ); + bInheritHandles, dwCreationFlags, + lpStartupInfo, lpProcessInfo ); break; case SCS_PIF_BINARY: @@ -1440,6 +1440,10 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) pwm->refCount++; LeaveCriticalSection(&PROCESS_Current()->crit_section); + + if (PROCESS_Current()->flags & PDB32_DEBUGGED) + DEBUG_SendLoadDLLEvent( -1 /*FIXME*/, pwm->module, pwm->modname ); + return pwm; } @@ -1591,7 +1595,11 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) /* Call process detach notifications */ if ( PROCESS_Current()->free_lib_count <= 1 ) + { MODULE_DllProcessDetach( FALSE, NULL ); + if (PROCESS_Current()->flags & PDB32_DEBUGGED) + DEBUG_SendUnloadDLLEvent( wm->module ); + } MODULE_FlushModrefs(); diff --git a/loader/ne/module.c b/loader/ne/module.c index a50a0a82dc9..20ba983584e 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -1031,7 +1031,7 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) pdb = PROCESS_Create( pModule, new_cmd_line, env, hInstance, hPrevInstance, - NULL, NULL, TRUE, &startup, &info ); + NULL, NULL, TRUE, 0, &startup, &info ); CloseHandle( info.hThread ); CloseHandle( info.hProcess ); @@ -1046,7 +1046,7 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) */ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) { HINSTANCE16 hInstance, hPrevInstance = 0; @@ -1118,7 +1118,7 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, if ( !PROCESS_Create( pModule, cmd_line, env, hInstance, hPrevInstance, - psa, tsa, inherit, startup, info ) ) + psa, tsa, inherit, flags, startup, info ) ) return FALSE; return TRUE; diff --git a/loader/pe_image.c b/loader/pe_image.c index 591058902e0..661393cc1e6 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -914,7 +914,7 @@ void PE_UnloadLibrary(WINE_MODREF *wm) */ BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, LPSTARTUPINFOA startup, + BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ) { LPCSTR modName = NULL; @@ -948,7 +948,7 @@ BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env, /* Create new process */ if ( !PROCESS_Create( pModule, cmd_line, env, - 0, 0, psa, tsa, inherit, startup, info ) ) + 0, 0, psa, tsa, inherit, flags, startup, info ) ) return FALSE; /* Note: PE_CreateModule and the remaining process initialization will diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index 403667ef96c..3abfa228c56 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -195,7 +195,7 @@ import ntdll.dll 177 stub CreateTapePartition 178 stdcall CreateThread(ptr long ptr long long ptr) CreateThread 179 stdcall CreateToolhelp32Snapshot(long long) CreateToolhelp32Snapshot -180 stub DebugActiveProcess +180 stdcall DebugActiveProcess(long) DebugActiveProcess # FIXME #181 register DebugBreak() DebugBreak 181 stub DebugBreak diff --git a/scheduler/process.c b/scheduler/process.c index fdbfa22151f..67213da5faa 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -526,6 +526,10 @@ void PROCESS_Start(void) entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32, OptionalHeader.AddressOfEntryPoint); + + if (pdb->flags & PDB32_DEBUGGED) + DEBUG_SendCreateProcessEvent( -1 /*FIXME*/, pModule->module32, entry ); + TRACE_(relay)("(entryproc=%p)\n", entry ); ExitProcess( entry(NULL) ); @@ -542,7 +546,7 @@ void PROCESS_Start(void) PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, STARTUPINFOA *startup, + BOOL inherit, DWORD flags, STARTUPINFOA *startup, PROCESS_INFORMATION *info ) { DWORD size, commit; @@ -559,9 +563,10 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, /* Create the process on the server side */ - req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); - req.inherit_all = inherit; - req.start_flags = startup->dwFlags; + req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); + req.inherit_all = inherit; + req.create_flags = flags; + req.start_flags = startup->dwFlags; if (startup->dwFlags & STARTF_USESTDHANDLES) { req.hstdin = startup->hStdInput; @@ -581,6 +586,10 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, info->hProcess = reply.handle; info->dwProcessId = (DWORD)pdb->server_pid; + if ((flags & DEBUG_PROCESS) || + ((parent->flags & PDB32_DEBUGGED) && !(flags & DEBUG_ONLY_THIS_PROCESS))) + pdb->flags |= PDB32_DEBUGGED; + if (pModule->module32) { /* Create the main thread */ diff --git a/scheduler/thread.c b/scheduler/thread.c index a2907349f82..1c61dd695d4 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -110,8 +110,8 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, stack_size = 1024 * 1024; if (stack_size >= 16*1024*1024) WARN("Thread stack size is %ld MB.\n",stack_size/1024/1024); - thdb->stack_base = VirtualAlloc(NULL, - stack_size + (alloc_stack16 ? 0x10000 : 0), + thdb->stack_base = VirtualAlloc(NULL, stack_size + SIGNAL_STACK_SIZE + + (alloc_stack16 ? 0x10000 : 0), MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (!thdb->stack_base) goto error; /* Set a guard page at the bottom of the stack */ @@ -119,7 +119,7 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, &old_prot ); thdb->teb.stack_top = (char *)thdb->stack_base + stack_size; thdb->teb.stack_low = thdb->stack_base; - thdb->exit_stack = thdb->teb.stack_top; + thdb->signal_stack = thdb->teb.stack_top; /* start of signal stack */ /* Allocate the 16-bit stack selector */ @@ -131,6 +131,7 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, if (!thdb->teb.stack_sel) goto error; thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( thdb->teb.stack_sel, 0x10000 - sizeof(STACK16FRAME) ); + thdb->signal_stack = (char *)thdb->signal_stack + 0x10000; } /* Create the thread event */ @@ -294,6 +295,9 @@ static void THREAD_Start(void) PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0, 0 ); PE_InitTls(); MODULE_DllThreadAttach( NULL ); + + if (thdb->process->flags & PDB32_DEBUGGED) DEBUG_SendCreateThreadEvent( func ); + ExitThread( func( thdb->entry_arg ) ); } diff --git a/win32/except.c b/win32/except.c index c455143cd7f..dad51bb9ac5 100644 --- a/win32/except.c +++ b/win32/except.c @@ -69,9 +69,12 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers) char message[80]; PDB *pdb = PROCESS_Current(); - /* FIXME: Should check if the process is being debugged */ - - if (pdb->top_filter) + if (pdb->flags & PDB32_DEBUGGED) + { + if (DEBUG_SendExceptionEvent( epointers->ExceptionRecord, FALSE ) == DBG_CONTINUE) + return EXCEPTION_CONTINUE_EXECUTION; + } + else if (pdb->top_filter) { DWORD ret = pdb->top_filter( epointers ); if (ret != EXCEPTION_CONTINUE_SEARCH) return ret;