diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c index fb5ea1581e2..55bcd62f379 100644 --- a/dlls/kernel32/tests/debugger.c +++ b/dlls/kernel32/tests/debugger.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wine/test.h" #include "wine/heap.h" #include "wine/rbtree.h" @@ -828,7 +829,9 @@ static void doChild(int argc, char **argv) { struct child_blackbox blackbox; const char *blackbox_file; - HANDLE parent; + WCHAR path[MAX_PATH]; + HMODULE mod; + HANDLE parent, file, map; DWORD ppid; BOOL debug; BOOL ret; @@ -876,10 +879,49 @@ static void doChild(int argc, char **argv) NtCurrentTeb()->Peb->BeingDebugged = TRUE; + mod = LoadLibraryW( L"ole32.dll" ); + FreeLibrary( mod ); + + GetSystemDirectoryW( path, MAX_PATH ); + wcscat( path, L"\\oleaut32.dll" ); + file = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + child_ok( file != INVALID_HANDLE_VALUE, "failed to open %s: %u\n", debugstr_w(path), GetLastError()); + map = CreateFileMappingW( file, NULL, SEC_IMAGE | PAGE_READONLY, 0, 0, NULL ); + child_ok( map != NULL, "failed to create mapping %s: %u\n", debugstr_w(path), GetLastError() ); + mod = MapViewOfFile( map, FILE_MAP_READ, 0, 0, 0 ); + child_ok( mod != NULL, "failed to map %s: %u\n", debugstr_w(path), GetLastError() ); + CloseHandle( file ); + CloseHandle( map ); + UnmapViewOfFile( mod ); + blackbox.failures = child_failures; save_blackbox(blackbox_file, &blackbox, sizeof(blackbox), NULL); } +static HMODULE ole32_mod, oleaut32_mod; + +static void check_dll_event( HANDLE process, DEBUG_EVENT *ev ) +{ + WCHAR *p, module[MAX_PATH]; + + switch (ev->dwDebugEventCode) + { + case CREATE_PROCESS_DEBUG_EVENT: + break; + case LOAD_DLL_DEBUG_EVENT: + if (!GetMappedFileNameW( process, ev->u.LoadDll.lpBaseOfDll, module, MAX_PATH )) module[0] = 0; + if ((p = wcsrchr( module, '\\' ))) p++; + else p = module; + if (!wcsicmp( p, L"ole32.dll" )) ole32_mod = ev->u.LoadDll.lpBaseOfDll; + else if (!wcsicmp( p, L"oleaut32.dll" )) oleaut32_mod = ev->u.LoadDll.lpBaseOfDll; + break; + case UNLOAD_DLL_DEBUG_EVENT: + if (ev->u.UnloadDll.lpBaseOfDll == ole32_mod) ole32_mod = (HMODULE)1; + if (ev->u.UnloadDll.lpBaseOfDll == oleaut32_mod) oleaut32_mod = (HMODULE)1; + break; + } +} + static void test_debug_loop(int argc, char **argv) { const char *arguments = " debugger child "; @@ -926,6 +968,7 @@ static void test_debug_loop(int argc, char **argv) if (!ret) break; if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; + check_dll_event( pi.hProcess, &ev ); #if defined(__i386__) || defined(__x86_64__) if (ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT && ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) @@ -940,6 +983,9 @@ static void test_debug_loop(int argc, char **argv) if (!ret) break; } + ok( ole32_mod == (HMODULE)1, "ole32.dll was not reported\n" ); + ok( oleaut32_mod == (HMODULE)1, "oleaut32.dll was not reported\n" ); + ret = CloseHandle(pi.hThread); ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError()); ret = CloseHandle(pi.hProcess); diff --git a/server/debugger.c b/server/debugger.c index 9f389075b92..2a2839f42ee 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -181,9 +181,7 @@ static void fill_exit_process_event( struct debug_event *event, const void *arg static void fill_load_dll_event( struct debug_event *event, const void *arg ) { - struct process *process = event->sender->process; - const struct process_dll *dll = arg; - struct memory_view *view = find_mapped_view( process, dll->base ); + const struct memory_view *view = arg; const pe_image_info_t *image_info = get_view_image_info( view, &event->data.load_dll.base ); event->data.load_dll.dbg_offset = image_info->dbg_offset; @@ -194,8 +192,8 @@ static void fill_load_dll_event( struct debug_event *event, const void *arg ) static void fill_unload_dll_event( struct debug_event *event, const void *arg ) { - const mod_handle_t *base = arg; - event->data.unload_dll.base = *base; + const struct memory_view *view = arg; + get_view_image_info( view, &event->data.unload_dll.base ); } typedef void (*fill_event_func)( struct debug_event *event, const void *arg ); @@ -534,39 +532,6 @@ void debugger_detach( struct process *process, struct debug_obj *debug_obj ) resume_process( process ); } -/* generate all startup events of a given process */ -void generate_startup_debug_events( struct process *process ) -{ - struct list *ptr; - struct memory_view *view = get_exe_view( process ); - struct thread *thread, *first_thread = get_process_first_thread( process ); - - if (!view) return; - generate_debug_event( first_thread, DbgCreateProcessStateChange, view ); - ptr = list_head( &process->dlls ); /* skip main module reported in create process event */ - - /* generate ntdll.dll load event */ - if (ptr && (ptr = list_next( &process->dlls, ptr ))) - { - struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry ); - generate_debug_event( first_thread, DbgLoadDllStateChange, dll ); - } - - /* generate creation events */ - LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry ) - { - if (thread != first_thread) - generate_debug_event( thread, DbgCreateThreadStateChange, NULL ); - } - - /* generate dll events (in loading order) */ - while (ptr && (ptr = list_next( &process->dlls, ptr ))) - { - struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry ); - generate_debug_event( first_thread, DbgLoadDllStateChange, dll ); - } -} - /* create a debug object */ DECL_HANDLER(create_debug_obj) { diff --git a/server/mapping.c b/server/mapping.c index 9728beca959..0e97391f74b 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -348,11 +348,15 @@ struct memory_view *get_exe_view( struct process *process ) } /* add a view to the process list */ -static void add_process_view( struct process *process, struct memory_view *view ) +static void add_process_view( struct thread *thread, struct memory_view *view ) { + struct process *process = thread->process; + if (view->flags & SEC_IMAGE) { - if (!is_process_init_done( process ) && !(view->image.image_charact & IMAGE_FILE_DLL)) + if (is_process_init_done( process )) + generate_debug_event( thread, DbgLoadDllStateChange, view ); + else if (!(view->image.image_charact & IMAGE_FILE_DLL)) { /* main exe */ list_add_head( &process->views, &view->entry ); @@ -1001,6 +1005,42 @@ int get_view_nt_name( const struct memory_view *view, struct unicode_str *name ) return 1; } +/* generate all startup events of a given process */ +void generate_startup_debug_events( struct process *process ) +{ + struct memory_view *view; + struct list *ptr = list_head( &process->views ); + struct thread *thread, *first_thread = get_process_first_thread( process ); + + if (!ptr) return; + view = LIST_ENTRY( ptr, struct memory_view, entry ); + generate_debug_event( first_thread, DbgCreateProcessStateChange, view ); + + /* generate ntdll.dll load event */ + while (ptr && (ptr = list_next( &process->views, ptr ))) + { + view = LIST_ENTRY( ptr, struct memory_view, entry ); + if (!(view->flags & SEC_IMAGE)) continue; + generate_debug_event( first_thread, DbgLoadDllStateChange, view ); + break; + } + + /* generate creation events */ + LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry ) + { + if (thread != first_thread) + generate_debug_event( thread, DbgCreateThreadStateChange, NULL ); + } + + /* generate dll events (in loading order) */ + while (ptr && (ptr = list_next( &process->views, ptr ))) + { + view = LIST_ENTRY( ptr, struct memory_view, entry ); + if (!(view->flags & SEC_IMAGE)) continue; + generate_debug_event( first_thread, DbgLoadDllStateChange, view ); + } +} + static void mapping_dump( struct object *obj, int verbose ) { struct mapping *mapping = (struct mapping *)obj; @@ -1142,7 +1182,7 @@ DECL_HANDLER(map_view) view->start = req->start; view->flags = SEC_IMAGE; memcpy( &view->image, get_req_data(), min( sizeof(view->image), get_req_data_size() )); - add_process_view( current->process, view ); + add_process_view( current, view ); return; } @@ -1173,12 +1213,10 @@ DECL_HANDLER(map_view) view->fd = !is_fd_removable( mapping->fd ) ? (struct fd *)grab_object( mapping->fd ) : NULL; view->committed = mapping->committed ? (struct ranges *)grab_object( mapping->committed ) : NULL; view->shared = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL; - if (mapping->flags & SEC_IMAGE) - { - view->image = mapping->image; - if (view->base != mapping->image.base) set_error( STATUS_IMAGE_NOT_AT_BASE ); - } - add_process_view( current->process, view ); + if (view->flags & SEC_IMAGE) view->image = mapping->image; + add_process_view( current, view ); + if (view->flags & SEC_IMAGE && view->base != mapping->image.base) + set_error( STATUS_IMAGE_NOT_AT_BASE ); } done: @@ -1190,7 +1228,9 @@ DECL_HANDLER(unmap_view) { struct memory_view *view = find_mapped_view( current->process, req->base ); - if (view) free_memory_view( view ); + if (!view) return; + if (view->flags & SEC_IMAGE) generate_debug_event( current, DbgUnloadDllStateChange, view ); + free_memory_view( view ); } /* get a range of committed pages in a file mapping */ diff --git a/server/process.c b/server/process.c index 229c8b44e95..dad45938015 100644 --- a/server/process.c +++ b/server/process.c @@ -832,7 +832,6 @@ static void process_unload_dll( struct process *process, mod_handle_t base ) free( dll->filename ); list_remove( &dll->entry ); free( dll ); - generate_debug_event( current, DbgUnloadDllStateChange, &base ); } else set_error( STATUS_INVALID_PARAMETER ); } @@ -1602,9 +1601,6 @@ DECL_HANDLER(load_dll) if ((dll = process_load_dll( current->process, req->base, get_req_data(), get_req_data_size() ))) { dll->name = req->name; - /* only generate event if initialization is done */ - if (is_process_init_done( current->process )) - generate_debug_event( current, DbgLoadDllStateChange, dll ); } }