Is there a cap on the number of modules WinDbg can see? - debugging

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 !

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

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}
}

Related

WinDbg shows some variables but not others, shows some variables in same location

I'm trying to use WinDbg 6.2.9200.16384 x64 over a serial cable to debug a driver I'm writing. WinDbg connects to the target machine (Windows 8) just fine, and I see all the dbgprints as the system boots and loads everything. I can load the symbols for my driver just fine and can set breakpoints, and when my driver hits those breakpoints, the system halts as expected. This is where things get weird: when I hit a breakpoint, I can only see some of the local variables in my function in both the locals window and when using the 'dv' command. I created a variable to test with:
int myInt = 8;
When I use a dbgprint to show the value of myInt, it works fine and I see it as 8. However, the variable doesn't even appear at all in the locals window or with the 'dv' command. Other variables do, such as
ULONG rcb = 0;
and I can see its value just fine in the locals window. These variables are literally declared one after the other.
Another symptom of this strange problem is this. I have a function
ULONG someFunction(UINT16 offset) {
ULONG rcb, tempAddr, temp, temp1;
ULONG writeAddr, readAddr;
UINT16 dev;
dev = 15;
...
}
I call this function like so:
someFunction(0x777);
When I set a breakpoint in this function and inspect the variable values with WinDbg, nothing makes any sense. First, it only sees 4 of my 8 variables, just offset, rcb, writeAddr, and readAddr. It tells me the value of offset is not 0x777 as I would expect, but 0xE061 (this changes each time I run the code). When I look closer at the locals window (same information is shown via 'dv' and '? varname' commands) I notice that the location of offset and the location of rcb are the exact same address. Likewise, writeAddr and readAddr are stored at the same address as well. None of the other variables are detected by the debugger.
I am convinced that I've loaded the symbols properly, the source and symbols paths are set correctly, I've run '.reload /f' a million times with no errors loading my driver's symbols. I'm still able to break and step through other lines of code, but the locals just don't make any sense. When I dbgprint, the correct values are shown so it seems like this is a problem with the debugger itself, not with my driver. Any ideas?
<>
Nowadays Compiler has been enhanced a lot to get better optimized binary with optimized performance and other metrics. Hence compiler store few variables as locals(visible via 'dv /v' command) and store other variables in their registers. That's the reason you didn't see variable int myInt in dv command. We can get to know which registers are being used for the variables, by disassembling the function using 'uf binary!functionname' or by viewing disassembled code in Windbg View-> Disassembly.
Note that the driver may behave little differently with and without optimization of the compiler in the aspects of performance, memory usage, etc. So its always recommended to debug the one generated from the default optimized compiler, as this is the one used in realtime user scenario.
I fixed the problem. To anyone else who runs into this same thing: I was working with a free build of the driver, so the compiler had optimized out a lot of my variables. To fix it, either compile a checked version of the driver, or add the line
MSC_OPTIMIZATION=/Od /Oi
to your sources file to disable optimizations for the free build. Hope this helps anyone with the same problem.

LLDB Break at Address

I apologize for the likely trivial question but I am running into a wall as Google gives me the same non-applicable answers over and over.
I am trying to set a breakpoint in LLDB. After reading the documentation, the options available to me are to either stop on a certain line in the source or on a certain symbol.
What I want to do is set a breakpoint on a certain memory location.
Not read-or-write to that memory location either but simply breaking when the instruction at that location is about to be executed.
In Pseudocode:
break 0x00010000
breaks when EIP points to 0x00010000.
How can I do this?
breakpoint set has an address option; you would type help breakpoint set to see all of them. For your specific example,
(lldb) br s -a 0x10000
(You can always use shorter versions of command names in lldb that are unambiguous so typing out breakpoint set isn't necessary)
The alternative is to use "process launch --stop-at-entry ...". This will allow you to set breakpoints after the program is launched and then "continue" will let you stop on your first breakpoint. Interestingly (testing in Ubuntu) using --stop-at-entry takes a lot longer to start (~3 seconds). I need to use this on OS X and maybe it will be quicker there.

Windbg with xp embedded, ntdll.dll symbols fail, other symbols affected?

I am using windbg with xp embedded. Attempting to fetch the operating system symbols fails with the message "Symbol file could not be found. Defaulted to export symbols for ntdll.dll". (Is this typical for xp embedded???)
I have no problem locating and loading symbols and source for my own code. However stepping through the code suggests there is a severe mismatch between the code and the symbol file as the location of variables in memory as returned by dv does not appear to agree with the actual memory contents (e.g. assign a variable, but afterwards, the address that dv claims corresponds to it doesn't appears unchanged).
My sympath lists the symbol directory first, then the cache, then the server so cached symbol files shouldn't be interfering.
Is this a latent effect of not finding the ntdll symbol files and using another one that doesn't match correctly or is there something else that could be causing this?
Example:
.sympath D:/Symbols
.symfix+
.srcpath D:/Symbols ** Yes, currently the source is in with the symbols
.reload
** (defaults to export symbols for ntdll.dll since symbol file can't be found)
bp 00401000 (break at a constructor)
g
(program runs till it hits constructor)
l+t
dv /i /t /V ** look up this pointer memory location to check constructor
** We bring up a memory window at the location the this pointer refers to and
** step through the code, but no changes appear in that memory window
** moreover a local LARGE_INTEGER whose value is set with QueryPerformanceCounter
** also appears unchanged after the call
** when the constructor returns we assign the memory address returned by
** new to a global pointer, whose memory address we look up with dt, but
** after the call that address still has 0 in it
Can anyone tell me how to actually fix this?
As a side note we actually run cdb as a server on the xp embedded machine and use the "connect to remote session" option of windbg. The above commands are all executed through windbg.
Executing !sym noisy before the .reload will let you know why it's not finding symbols for ntdll.dll. It's entirely possible that they're simply not indexed on the symbol server, which generally means you are out of luck (there really isn't anyone to contact to get this fixed unfortunately).
As for your other symbol issues:
1) Is this the release build of your code? If so, it's entirely expected
2) If it is the debug build, are you 100% sure that the source you're pointing to matches the target machine? Make sure you're 100% before answering :)
-scott

How to attach to a already running process noninvasively

I have a process suspended at breakpoint under visual studio debugger.
I can attach as many as cdb (Microsoft's console debugger) in non-invasive mode as
cdb -p pid -pvr
How to achieve the same using my own program which uses Debug Engine API.
IDebugClient* debugClient = 0;
(DebugCreate( __uuidof(IDebugClient), (void **)&debugClient );
debugClient->AttachProcess(0,id,DEBUG_ATTACH_NONINVASIVE
|DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND);
This code causes E_INVALIDARG. Is this combination is not allowed ? The one below works, but when it calls GetStackTrace, it returns E_UNEXPECTED.
debugClient->AttachProcess(0,id,DEBUG_ATTACH_NONINVASIVE);
debugControl->GetStackTrace(0, 0, 0, pStackFrames, maxFrames, &framesFilled);
I am interested to attach to a process already at debug break noninvasive way , and get a few local variable from its current stack & some global variable value.
Secondly, can someone point me the function used to dump the content of memory for a symbol iteratively like !stl does. I need to write a plugin to dump one of my vector like structure.
Thanks
I believe there's nothing wrong with
DEBUG_ATTACH_NONINVASIVE|DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND
combination - it is perfectly permissible and is even featured in assert sample.
Otherwise, as far as documentation goes - it is not that detailed. I would suggest debugging your extension with the help of wt (trace and watch data) - it is particularly useful when you need to locate the exact subroutine that is returning an error which might provide you with better insight on the problem.
As for remotely accessing typed data in your apps from an extension, I've found ExtRemoteTyped class (available in engextcpp.hpp in the sdk subfolder) to be very helpful and intuitive to use.

In WinDbg, can I use software breakpoints without having symbols?

I'm having trouble using software breakpoints in WinDbg in order to break in a given address.
It's a Visual C++ 6.0 MFC executable without symbols (belive me, I just can not generate the symbols).
Suppose my executable image is named image00400000. Using Software Breakpoints (bp):
0:000> bp image00400000 + 0x003ba1eb
0:000> bl
0 e 007ba1eb 0001 (0001) 0:**** image00400000+0x3ba1eb
0:000> g
I get the relative address (0x003ba1eb) from the .map file (this one I got it). I pick up a line which I'm sure that will be executed, but there is no stop at all...
Does anyone have any ideas? I'd appreciate them. Thank you!
PD: If there's anything left to explain or you need more info, just drop me a comment :-)
Sorry I'm not allowed to create comments yet (too new) to SO.
It is a bit tricky to be specific with the information available. I guess it is possible that the breakpoint address isn't calculated correctly. Given the situation I would attempt to calculate the breakpoint address as: Module start + code start + code offset from the map file. Maybe this is what you did (unless I got it wrong ;-) )
Also worth noting that the bp address needs to align on an instruction boundary. If it doesn't then it won't be set properly. This could be possible if you are having to guess at trying to get a breakpoint into a particular function.
It might be helpful to outline a little more about the condition under which you want the program to stop in the debugger.
To add symbols, you need to make a debug build
BUILD menu item
Set Active Configuration
Select the Debug Configuration, instead of the release configuration.
Rebuild everything, and your symbols should be there.

Resources