diff options
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r-- | gdb/windows-nat.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index e32c701..f0545fc 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -847,11 +847,31 @@ handle_load_dll (void *dummy) dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; + /* Try getting the DLL name by searching the list of known modules + and matching their base address against this new DLL's base address. + + FIXME: brobecker/2013-12-10: + It seems odd to be going through this search if the DLL name could + simply be extracted via "event->lpImageName". Moreover, some + experimentation with various versions of Windows seem to indicate + that it might still be too early for this DLL to be listed when + querying the system about the current list of modules, thus making + this attempt pointless. + + This code can therefore probably be removed. But at the time of + this writing, we are too close to creating the GDB 7.7 branch + for us to make such a change. We are therefore defering it. */ + if (!get_module_name (event->lpBaseOfDll, dll_buf)) dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; dll_name = dll_buf; + /* Try getting the DLL name via the lpImageName field of the event. + Note that Microsoft documents this fields as strictly optional, + in the sense that it might be NULL. And the first DLL event in + particular is explicitly documented as "likely not pass[ed]" + (source: MSDN LOAD_DLL_DEBUG_INFO structure). */ if (*dll_name == '\0') dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode); @@ -1703,6 +1723,64 @@ 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. */ + +static void +windows_ensure_ntdll_loaded (void) +{ + struct so_list *so; + HMODULE dummy_hmodule; + DWORD cb_needed; + 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; + + if (cb_needed < 1) + return; + + hmodules = (HMODULE *) alloca (cb_needed); + if (EnumProcessModules (current_process_handle, hmodules, + cb_needed, &cb_needed) == 0) + return; + + for (i = 0; i < (int) (cb_needed / sizeof (HMODULE)); i++) + { + MODULEINFO mi; + char dll_name[__PMAX]; + + if (GetModuleInformation (current_process_handle, hmodules[i], + &mi, sizeof (mi)) == 0) + continue; + if (GetModuleFileNameEx (current_process_handle, hmodules[i], + dll_name, sizeof (dll_name)) == 0) + continue; + if (FILENAME_CMP (lbasename (dll_name), "ntdll.dll") == 0) + { + solib_end->next = windows_make_so (dll_name, mi.lpBaseOfDll); + solib_end = solib_end->next; + return; + } + } +} + static void do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) { @@ -1756,6 +1834,14 @@ 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 (); + windows_initialization_done = 1; inf->control.stop_soon = NO_STOP_QUIETLY; stop_after_trap = 0; |