From ea39ad355eb72b296b30a66bbc81256a071e8f1e Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Mon, 3 Feb 2014 08:32:40 +0100 Subject: [PATCH] Ignore DLL load/unload events during inferior initialization. This patch aims at simplifying DLL handling during the inferior initialization (process creation during the "run", or during an "attach"). Instead of processing each DLL load event, which is sometimes incomplete, we ignore these events until the inferior has completed its startup phase, and then just iterate over all DLLs via EnumProcessModules. gdb/ChangeLog: * windows-nat.c (get_windows_debug_event): Ignore LOAD_DLL_DEBUG_EVENT and UNLOAD_DLL_DEBUG_EVENT if windows_initialization_done == 0. (windows_add_all_dlls): Renames windows_ensure_ntdll_loaded. Adjust implementation to always load all DLLs. (do_initial_windows_stuff): Replace call to windows_ensure_ntdll_loaded by call to windows_add_all_dlls. --- gdb/ChangeLog | 10 ++++++++++ gdb/windows-nat.c | 45 ++++++++++++--------------------------------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 43a25390b9a..a4e27f572ea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2014-02-20 Joel Brobecker + + * windows-nat.c (get_windows_debug_event): Ignore + LOAD_DLL_DEBUG_EVENT and UNLOAD_DLL_DEBUG_EVENT + if windows_initialization_done == 0. + (windows_add_all_dlls): Renames windows_ensure_ntdll_loaded. + Adjust implementation to always load all DLLs. + (do_initial_windows_stuff): Replace call to + windows_ensure_ntdll_loaded by call to windows_add_all_dlls. + 2014-02-20 Joel Brobecker * windows-nat.c (_initialize_windows_nat): Deprecate the diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index f5fb34bf82a..54804a8bbd6 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1576,7 +1576,7 @@ get_windows_debug_event (struct target_ops *ops, (unsigned) current_event.dwThreadId, "LOAD_DLL_DEBUG_EVENT")); CloseHandle (current_event.u.LoadDll.hFile); - if (saw_create != 1) + if (saw_create != 1 || ! windows_initialization_done) break; catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; @@ -1589,7 +1589,7 @@ get_windows_debug_event (struct target_ops *ops, (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId, "UNLOAD_DLL_DEBUG_EVENT")); - if (saw_create != 1) + if (saw_create != 1 || ! windows_initialization_done) break; catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; @@ -1722,21 +1722,11 @@ windows_wait (struct target_ops *ops, } } -/* On certain versions of Windows, the information about ntdll.dll - is not available yet at the time we get the LOAD_DLL_DEBUG_EVENT, - thus preventing us from reporting this DLL as an SO. This has been - witnessed on Windows 8.1, for instance. A possible explanation - is that ntdll.dll might be mapped before the SO info gets created - by the Windows system -- ntdll.dll is the first DLL to be reported - via LOAD_DLL_DEBUG_EVENT and other DLLs do not seem to suffer from - that problem. - - If we indeed are missing ntdll.dll, this function tries to recover - from this issue, after the fact. Do nothing if we encounter any - issue trying to locate that DLL. */ +/* Iterate over all DLLs currently mapped by our inferior, and + add them to our list of solibs. */ static void -windows_ensure_ntdll_loaded (void) +windows_add_all_dlls (void) { struct so_list *so; HMODULE dummy_hmodule; @@ -1744,10 +1734,6 @@ windows_ensure_ntdll_loaded (void) HMODULE *hmodules; int i; - for (so = solib_start.next; so != NULL; so = so->next) - if (FILENAME_CMP (lbasename (so->so_name), "ntdll.dll") == 0) - return; /* ntdll.dll already loaded, nothing to do. */ - if (EnumProcessModules (current_process_handle, &dummy_hmodule, sizeof (HMODULE), &cb_needed) == 0) return; @@ -1760,7 +1746,7 @@ windows_ensure_ntdll_loaded (void) cb_needed, &cb_needed) == 0) return; - for (i = 0; i < (int) (cb_needed / sizeof (HMODULE)); i++) + for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++) { MODULEINFO mi; #ifdef __USEWIDE @@ -1781,12 +1767,9 @@ windows_ensure_ntdll_loaded (void) #else name = dll_name; #endif - if (FILENAME_CMP (lbasename (name), "ntdll.dll") == 0) - { - solib_end->next = windows_make_so (name, mi.lpBaseOfDll); - solib_end = solib_end->next; - return; - } + + solib_end->next = windows_make_so (name, mi.lpBaseOfDll); + solib_end = solib_end->next; } } @@ -1843,13 +1826,9 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) break; } - /* FIXME: brobecker/2013-12-10: We should try another approach where - we first ignore all DLL load/unload events up until this point, - and then iterate over all modules to create the associated shared - objects. This is a fairly significant change, however, and we are - close to creating a release branch, so we are delaying it a bit, - after the branch is created. */ - windows_ensure_ntdll_loaded (); + /* Now that the inferior has been started and all DLLs have been mapped, + we can iterate over all DLLs and load them in. */ + windows_add_all_dlls (); windows_initialization_done = 1; inf->control.stop_soon = NO_STOP_QUIETLY; -- 2.30.2