From: Pedro Alves <palves@redhat.com>
To: Joel Brobecker <brobecker@adacore.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [RFA] nameless LOAD_DLL_DEBUG_EVENT causes ntdll.dll to be missing
Date: Thu, 05 Dec 2013 12:38:00 -0000 [thread overview]
Message-ID: <52A073CC.3050009@redhat.com> (raw)
In-Reply-To: <20131205105437.GE3175@adacore.com>
Hi Joel,
Thanks for investigating further.
On 12/05/2013 10:54 AM, Joel Brobecker wrote:
>>> % gnatmake -g a -bargs -shared
>>> % gdb a
>>> (gdb) start
> [...]
>> Does this happen only on "attach", or also with "run"? I ask
>> because of this:
>
> It only happens on "run". I think I have a pretty good handle on what
> is going on, now, thanks to your inquisitive questions.
>
> First, something that was not obvious, and yet gave me an "aha!"
> moment. At the time the LOAD_DLL_DEBUG_EVENT happens, it turns
> out that the modules-array snapshot returned by EnumProcessModules
> does not include the DLL being loaded yet. When I started instrumenting
> the code in get_module_name, I looked at the result of cbNeeded by
> sizeof (HMODULE), and on the first call (first DLL) it fails, then
> return 2, 3, 4, etc, and the base address of the new element at
> the end of the array always corresponds to the base address of
> the _previous_ LOAD_DLL_DEBUG_EVENT, not the one being processed.
> The reason why it did not catch the first time I looked at it is
> because the first element at index 0 must be for the main executable.
> Certainly the base address corresponds.
>
> With that in mind, we can see that during the inferior startup
> phase (when we "run"), calling "get_image_name" is hopeless.
> But it is also unnecessary, since, most of the time, we get in
> the event an address in inferior memory where the path to the
> relevant DLL is stored (event->lpImageName). All we have to do
> is read that address, which we do but only after having tried
> the first method of iterating over all process modules.
>
> During "attach", on the other hand, the program has had time
> to correctly set the entire array, so we get a full array
> each time we process the LOAD_DLL_DEBUG_EVENT, allowing us
> resolve the DLL name that way.
>
> Now, back to the original problem, the difference between 2012
> and older versions is the fact that, in older versions, the
> LOAD_DLL_DEBUG_EVENT data for ntdll.dll provided the event->lpImageName
> is set, and we can read the DLL's path that way. But with 2012,
> it's null for this DLL. MSDN says it may happen:
>
> This member is strictly optional. Debuggers must be prepared to
> handle the case where lpImageName is NULL or *lpImageName (in the
> address space of the process being debugged) is NULL
>
> And I just reacted to the following bit:
>
> ... and it will __NOT__ likely pass an image name for the __first__
> DLL event ...
>
> Sounds familiar?
:-) I'd be good to have this new info distilled as a comment
in the code, IMO.
> So, back to the suggestion I made for the future (post 7.7), I think
> we should ignore the LOAD_DLL_DEBUG_EVENT events during
> do_initial_windows_stuff, and just rely on EnumProcessModules
> at the end of that function, once we're in control of the inferior.
> But that's a major change, and given the number of versions of
> Windows, multiplied by 2 for 32bits vs 64 bits - this is why I do
> not suggest it for now. But I can work on that sometime next year,
> to explore how well we would do.
>
> This is modulo the issue of EnumProcessModules' availability.
>
>> EnumProcessModules used to be exported by psapi.dll in older Windows
>> versions (I think prior to Windows 7), I don't think we can assume
>> that API/dll is always around.
>
> We don't. We load the DLL explicitly in GDB, and then set things up
> so that EnumProcessModules points either to the function in that DLL,
> or else to bad_EnumProcessModules. If not available, the fallback
> function returns a failure, which is correctly handled. In our case,
> it will NOT be used, and in older versions of Windows, the issue
> should not exist.
Right, I was aware of that LoadLibrary trick in use. I do think
we do still use it on newer Windows, though in those, the functions
moved to kernel32.dll and psapi.dll is just a wrapper.
> I hadn't checked, but it looks like we have the very same issue.
> I just build gdbserver (we don't use it on that platform), and
> after connecting to GDBserver, I don't see "ntdll.dll" in the
> output of "info shared" :-(. Even after setting a breakpoint inside
> the program and continuing to that breakpoint, new DLLs appear,
> but not ntdll.dll.
>
> I think the same long-term treatment would apply to GDBserver,
> and solve the problem as a result.
Yes.
> For the immediate problem,
> I could attempt a fix, but I am not sure how well I could test it.
I think the fix is very low risk, and could go in with minimal
testing.
> In the meantime, does the GDB-side fix look OK to commit to you
> (modulo the small issue you raised)?
Yes.
One nit -- does ntdll.dll appears at the end of the
loaded list with this fix, or at the beginning? I'd think
it should be the first dll in "info sharedlibrary", assuming
that that's what we see on older Windows versions.
--
Pedro Alves
next prev parent reply other threads:[~2013-12-05 12:38 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-03 11:31 Joel Brobecker
2013-12-03 19:51 ` Pedro Alves
2013-12-03 20:11 ` Eli Zaretskii
2013-12-05 10:54 ` Joel Brobecker
2013-12-05 12:38 ` Pedro Alves [this message]
2013-12-09 11:33 ` Joel Brobecker
2013-12-09 17:08 ` Pedro Alves
2013-12-10 10:06 ` pushed: " Joel Brobecker
2013-12-10 10:06 ` Joel Brobecker
2013-12-10 10:56 ` Joel Brobecker
2013-12-10 13:41 ` Pedro Alves
2013-12-10 13:58 ` Pedro Alves
2013-12-12 18:18 ` Joel Brobecker
2013-12-12 18:51 ` Eli Zaretskii
2013-12-12 19:08 ` Pedro Alves
2013-12-12 22:06 ` Tom Tromey
2013-12-13 10:06 ` Pedro Alves
2013-12-13 11:04 ` Joel Brobecker
2013-12-13 11:21 ` Pedro Alves
2013-12-13 19:38 ` Tom Tromey
2013-12-13 14:17 ` Joel Brobecker
2013-12-13 14:42 ` Pedro Alves
2013-12-13 15:45 ` Joel Brobecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52A073CC.3050009@redhat.com \
--to=palves@redhat.com \
--cc=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox