From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10738 invoked by alias); 13 Dec 2013 14:17:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 10728 invoked by uid 89); 13 Dec 2013 14:17:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 13 Dec 2013 14:17:27 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id DF957116577; Fri, 13 Dec 2013 09:18:04 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id kU0zhJxj0SYp; Fri, 13 Dec 2013 09:18:04 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id A6DA41164BA; Fri, 13 Dec 2013 09:18:04 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id C2406E07DF; Fri, 13 Dec 2013 15:17:23 +0100 (CET) Date: Fri, 13 Dec 2013 14:17:00 -0000 From: Joel Brobecker To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [RFA] nameless LOAD_DLL_DEBUG_EVENT causes ntdll.dll to be missing Message-ID: <20131213141723.GB3255@adacore.com> References: <1386070185-8020-1-git-send-email-brobecker@adacore.com> <529E361B.7070807@redhat.com> <20131205105437.GE3175@adacore.com> <52A073CC.3050009@redhat.com> <20131209113333.GC4011@adacore.com> <20131210105624.GA14056@adacore.com> <52A719F1.6060906@redhat.com> <52A71DDC.2080908@redhat.com> <20131212181843.GB3528@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="BXVAT5kNtrzKuDFl" Content-Disposition: inline In-Reply-To: <20131212181843.GB3528@adacore.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2013-12/txt/msg00530.txt.bz2 --BXVAT5kNtrzKuDFl Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 809 > I'll also add comments and documentation, if we decide to move forward. Here is an updated patch. Compared to the last one, I moved the linking of safe-ctype.o and lbasename.o to configure.srv instead of Makefile.in::OBS, so only Windows builds are affected. I also copy/pasted the comment from windows-nat.c to document the new function. gdb/gdbserver/ChangeLog: * Makefile.in (safe-ctype.o, lbasename.o): New rules. * configure.srv: Add safe-ctype.o and lbasename.o to srv_tgtobj for all targets that use win32-low.c. * win32-low.c (win32_ensure_ntdll_loaded): New function. (do_initial_child_stuff): Add call to win32_ensure_ntdll_loaded. I tested the patch on both x86_64-windows and also x86-windows. OK to commit this version? (I can take care of checking in your patch) Thank you, -- Joel --BXVAT5kNtrzKuDFl Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-gdbserver-nameless-LOAD_DLL_DEBUG_EVENT-causes-ntdll.patch" Content-length: 7078 >From 362d97dbeca5ad34e7cea715c3a67e8bfc9ce819 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Thu, 12 Dec 2013 12:53:45 -0500 Subject: [PATCH] [gdbserver] nameless LOAD_DLL_DEBUG_EVENT causes ntdll.dll to be missing This is the gdbserver-equivalent of the change made in GDB to handle the case, in x64 windows version 2012, where the kernel produces a LOAD_DLL_DEBUG_EVENT where the name of the associated DLL cannot be determined at that time, and thus has to be processed later. The visible symptom is that ntdll.dll is missing from the list of shared libraries known to be mapped by the inferior, with other side-effects such as failure to unwind through code provided by that DLL (such as exception handling routines). gdb/gdbserver/ChangeLog: * Makefile.in (safe-ctype.o, lbasename.o): New rules. * configure.srv: Add safe-ctype.o and lbasename.o to srv_tgtobj for all targets that use win32-low.c. * win32-low.c (win32_ensure_ntdll_loaded): New function. (do_initial_child_stuff): Add call to win32_ensure_ntdll_loaded. --- gdb/gdbserver/Makefile.in | 6 +++ gdb/gdbserver/configure.srv | 6 +++ gdb/gdbserver/win32-low.c | 81 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 0 deletions(-) diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 641ea17..c8d971b 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -543,6 +543,12 @@ vasprintf.o: $(srcdir)/../../libiberty/vasprintf.c vsnprintf.o: $(srcdir)/../../libiberty/vsnprintf.c $(COMPILE) $< $(POSTCOMPILE) +safe-ctype.o: $(srcdir)/../../libiberty/safe-ctype.c + $(COMPILE) $< + $(POSTCOMPILE) +lbasename.o: $(srcdir)/../../libiberty/lbasename.c + $(COMPILE) $< + $(POSTCOMPILE) aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 32d935a..f4e6154 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -77,6 +77,7 @@ case "${target}" in ;; arm*-*-mingw32ce*) srv_regobj=reg-arm.o srv_tgtobj="win32-low.o win32-arm-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_tgtobj="${srv_tgtobj} wincecompat.o" # hostio_last_error implementation is in win32-low.c srv_hostio_err_objs="" @@ -100,6 +101,7 @@ case "${target}" in ;; i[34567]86-*-cygwin*) srv_regobj="$srv_i386_regobj" srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_xmlfiles="$srv_i386_xmlfiles" ;; i[34567]86-*-linux*) srv_regobj="$srv_i386_linux_regobj" @@ -126,6 +128,7 @@ case "${target}" in i[34567]86-*-mingw32ce*) srv_regobj="$srv_i386_regobj" srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_tgtobj="${srv_tgtobj} wincecompat.o" srv_xmlfiles="$srv_i386_xmlfiles" # hostio_last_error implementation is in win32-low.c @@ -135,6 +138,7 @@ case "${target}" in ;; i[34567]86-*-mingw*) srv_regobj="$srv_i386_regobj" srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_xmlfiles="$srv_i386_xmlfiles" srv_mingw=yes ;; @@ -326,11 +330,13 @@ case "${target}" in ;; x86_64-*-mingw*) srv_regobj="$srv_amd64_regobj" srv_tgtobj="i386-low.o i387-fp.o win32-low.o win32-i386-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_xmlfiles="$srv_i386_xmlfiles $srv_amd64_xmlfiles" srv_mingw=yes ;; x86_64-*-cygwin*) srv_regobj="$srv_amd64_regobj" srv_tgtobj="i386-low.o i387-fp.o win32-low.o win32-i386-low.o" + srv_tgtobj="${srv_tgtobj} safe-ctype.o lbasename.o" srv_xmlfiles="$srv_i386_xmlfiles" ;; diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index a4c9e77..91e24a0 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -105,6 +105,7 @@ typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD); static ptid_t win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options); static void win32_resume (struct thread_resume *resume_info, size_t n); +static void win32_ensure_ntdll_loaded (void); /* Get the thread ID from the current selected inferior (the current thread). */ @@ -371,6 +372,8 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) win32_resume (&resume, 1); } } + + win32_ensure_ntdll_loaded (); } /* Resume all artificially suspended threads if we are continuing @@ -1134,6 +1137,84 @@ failed: return 0; } +/* 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 +win32_ensure_ntdll_loaded (void) +{ + struct inferior_list_entry *dll_e; + size_t i; + HMODULE dh_buf[1]; + HMODULE *DllHandle = dh_buf; + DWORD cbNeeded; + BOOL ok; + + for (dll_e = all_dlls.head; dll_e != NULL; dll_e = dll_e->next) + { + struct dll_info *dll = (struct dll_info *) dll_e; + + if (strcasecmp (lbasename (dll->name), "ntdll.dll") == 0) + return; + } + + if (!load_psapi ()) + return; + + cbNeeded = 0; + ok = (*win32_EnumProcessModules) (current_process_handle, + DllHandle, + sizeof (HMODULE), + &cbNeeded); + + if (!ok || !cbNeeded) + return; + + DllHandle = (HMODULE *) alloca (cbNeeded); + if (!DllHandle) + return; + + ok = (*win32_EnumProcessModules) (current_process_handle, + DllHandle, + cbNeeded, + &cbNeeded); + if (!ok) + return; + + for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++) + { + MODULEINFO mi; + char dll_name[MAX_PATH]; + + if (!(*win32_GetModuleInformation) (current_process_handle, + DllHandle[i], + &mi, + sizeof (mi))) + continue; + if ((*win32_GetModuleFileNameExA) (current_process_handle, + DllHandle[i], + dll_name, + MAX_PATH) == 0) + continue; + if (strcasecmp (lbasename (dll_name), "ntdll.dll") == 0) + { + win32_add_one_solib (dll_name, + (CORE_ADDR) (uintptr_t) mi.lpBaseOfDll); + return; + } + } +} + typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD); typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32); typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32); -- 1.7.9 --BXVAT5kNtrzKuDFl--