Is there a cap on the number of modules WinDbg can

2019-06-21 06:30发布

问题:

Does anyone know if there is a cap on the number of DLLs WinDbg can see ? I believe Visual Studio was once capped at 500 but I can't find a source for this claim outside of some second hand accounts at work.

I'm trying to debug a hairy scenario and WinDbg's stack trace is incomplete. According to Process Explorer, the module I'm interested in is loaded but it doesn't show up in the output of 'lm' in WinDbg.

Suspiciously, said output is exactly 500 modules long, even though I know there are many more than that loaded, leading me to believe WinDbg isn't seeing DLLs beyond the first 500. Can anyone confirm ? Or suggest some other reason why a loaded module might not show up in 'lm' ?


Edit: upon further investigation, I was able to get WinDbg to load see the module I needed by attaching the debugger earlier, before that module was loaded.

It seems to me that, upon attaching to a process, the debugger engine will only see the first 500 dlls but will process subsequent loads correctly. I would still love confirmation from a WinDbg expert though, or better yet, a bypass to process more than 500 modules when attaching !

回答1:

I have expired that due to corruption in the module list windbg has not displayed all modules. Here is a script (found in the Windbg help file) which I have used on 32 bits xp userdumps. when hunting for modules not found in the lm output. You can also try the !dlls in windbg.

    $$ run with:  $$>< C:\DbgScripts\walkLdr.txt
    $$
    $$ Get module list LIST_ENTRY in $t0.
    r? $t0 = &@$peb->Ldr->InLoadOrderModuleList
    $$ Iterate over all modules in list.
    .for (r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0;
          (@$t1 != 0) & (@$t1 != @$t0);
          r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)@$t1->InLoadOrderLinks.Flink)
    {
        $$ Get base address in $Base.
        as /x ${/v:$Base} @@c++(@$t1->DllBase)

        $$ Get full name into $Mod.
        as /msu ${/v:$Mod} @@c++(&@$t1->FullDllName)

        .block
        {
            .echo ${$Mod} at ${$Base}
        }
        ad ${/v:$Base}
        ad ${/v:$Mod}
    }


回答2:

There is a registry key controlling the number of debugger messages a debugger can see. When you increase the value to e.g. 2048 you can see all loaded dlls.

Here is the relevant key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

DWORD DebuggerMaxModuleMsgs = e.g. 2048