I'm debugging dump files, while I have access to the symbol files.
I'm using a script, which combines the results of following windbg commands:
x /2 *!* // which types are present in the symbol files?
!heap -h 0 // which memory address ranges are used in the dump?
(At least, that's how I understand it. In case I'm wrong don't hesitate to correct me)
The result of the script (called heap_stat.py, found under this list of Windbg extensions) is a list of memory addresses, followed by their type. By taking statistics of those I can derive if there is a memory leak.
In top of this, using the WinDbg command dt CStringArray m_nSize of the mentioned memory address (in the specific case of a CStringArray, of course), I can see the total amount of entries of the used CStringArray objects, and see if there are CStringArray objects with lots of entries.
However there is a drawback to this system:
When I find such a CStringArray object with a lot of entries, I'm stuck there because out of all the CStringArray objects in my application, I have no idea which one I'm dealing with.
One thing which might help is the name of the local variable the memory address is about, but there's the catch: I don't know if this information is present and in case yes, can I find it in the symbol file or in the dump, and (obviously) which command do I need to run in order to get this information (I didn't find a flag that makes dt <flag> <memory address> return the local variable name, occupied by <memory address>)?
Can anybody help me?
For clarification purposes, this is how the result of my script currently looks like:
0x0065a4d0 mfc110u!CStringArray Size:[1]
0x0065a4e4 mfc110u!CStringArray Size:[0]
0x0065a4f8 mfc110u!CStringArray Size:[295926]
0x0065a520 mfc110u!CStringArray Size:[0]
As you can see, I can see the memory address where my variable is stored, I can see the type (retrieved from the symbols files), and I can see the amount of entries (retrieved from the dt Windbg command), but I'd like to have an output like the following:
0x0065a4d0 mfc110u!CStringArray Size:[1] var1
0x0065a4e4 mfc110u!CStringArray Size:[0] var2
0x0065a4f8 mfc110u!CStringArray Size:[295926] var3
0x0065a520 mfc110u!CStringArray Size:[0] var3
or:
0x0065a4d0 mfc110u!CStringArray Size:[1] obj1.prop1
0x0065a4e4 mfc110u!CStringArray Size:[0] obj2.prop1
0x0065a4f8 mfc110u!CStringArray Size:[295926] obj1.prop2
0x0065a520 mfc110u!CStringArray Size:[0] obj1.prop2
Such an output would indicate me that I need to verify what is happening to var3 or obj1.prop2 in the source code.
I wrote the following MFC application (partial source):
As you can see, the second CStringArray has multiple names:
anotherarray,a,tempandholycow.Observation 1: there will not be an easy 1:1 mapping on memory addresses and variable names.
Local variable names are available from the PDB files:
Note that the names
aandtempare not visible.Observation 2: variable names will be limited to their scope. If you want to remember all variable names, you would need to track all functions.
Above was a debug build. The release build is different:
Note that
holycowis missing.Observation 3: in release builds, variables might not be needed (optimized) and therefore not present.
Overall conclusion: it's not possible to map memory addresses to variable names.