I have taken the memory dump of a running process (Task manager, right-click, "Create dump file", and now I'm investigating it using Windbg.
!Dumpheap -stat
has revealed an enormous amount of objects, which seem to be collections of 14 entries: the end of the !Dumpheap -stat
looks as follows (the first two columns contain hyperlinks):
3f62cc58 70b7d878 68
3f62cc9c 70b7d878 68
3f62cce0 70b7d878 68
3f62cd24 70b7d878 68
3f62cd68 70b7d878 68
Clicking on such an object reveals the following:
0:000> !DumpObj /d 3f62ebb0
Name: System.Object[]
MethodTable: 70b7d878
EEClass: 70754b80
Size: 68(0x44) bytes
Array: Rank 1, Number of elements 14, Type CLASS (Print Array)
Fields:
None
Clicking on "Print Array" gives this:
0:000> !DumpArray /d 3f62ebb0
Name: System.Object[]
MethodTable: 70b7d878
EEClass: 70754b80
Size: 68(0x44) bytes
Array: Rank 1, Number of elements 14, Type CLASS
Element Methodtable: 70b7d824
[0] null
[1] 38f2cfd8
[2] null
[3] null
[4] null
[5] null
[6] null
[7] null
[8] null
[9] null
[10] null
[11] null
[12] null
[13] null
I would like to have more information, more especially what kind of collections those things are. In order to do that, I have thought of loading the debugging symbols and showing the module name.
Showing the module name : how do I do that? How can I see to which module an object belongs?
loading debugging symbols: how do I do that? I have put some "*.pdb" files in a directory and have filled in "File", "Symbol File Path" as C:\Temp_Folder\
and C:\Temp_Folder\*
but in both cases, the modules stay deferred:
0:000> lm
start end module name
00480000 004b8000 application_being_debugged (deferred)
1ce60000 1ce63000 security (deferred)
1d900000 1d91b000 opccomn_ps (deferred)
1d930000 1d956000 opcproxy (deferred)
I hope that, managing to configure the debugging symbol path, might reveal a lot of information.
Does anybody know how to do this?
Thanks in advance
I have taken the memory dump of a running process [...]
To give better directions, it would be important to know why you created the memory dump. Just for fun, for learning or for doing a real analysis? If it's a real analysis, what kind of analysis? Do you want to find out about high memory usage, a hang, a performance issue (CPU spike) or does your application crash?
[...] (Task manager, right-click, "Create dump file", and now I'm investigating it using Windbg.
You didn't report any problems with your dump, but be aware that Task Manager is not necessarily the best choice. There are two versions of Task Manager, the 32 bit version and the 64 bit version and each of them takes the memory dump in that bitness. Check out other options for creating a crash dump, which might be better suitable, depending on the why question.
!Dumpheap -stat
has revealed an enormous amount of objects, [...]
That's normal. A simple Hello World style WinForms application with an empty window has more than 5000 objects, when you might be thinking you only have 1 form.
When you say "enormous", that's hard to put into context. It's better to be precise when it comes to debugging. Say "!Dumpheap lists 123.000.468 objects".
the end of the
!Dumpheap -stat
looks as follows
No, sorry. Either something is ultimately broken in your app or this is simply not the output of !dumpheap -stat
. !dumpheap -stat
has 4 columns:
What you posted might be a part of the output of !dumpheap
(without -stat
). And that's typically not very useful, without prior knowledge of what one's looking for.
[...] what kind of collections those things are
Well, a System.Object[]
is an array of type System.Object
, typically declared in C# as object[]
. There's nothing more to say about this collection.
Other collections may be System.Windows.Forms.Control[]
or 2D arrays like System.Int32[][]
or System.Collections.Generic.List'1[[System.Windows.Forms.Application+ParkingWindow, System.Windows.Forms]]
which is a generic List<ParkingWindow>
in C# code.
I have thought of loading the debugging symbols
That's a very good idea. Without symbols, debugging is not worth it.
Showing the module name : how do I do that?
You can show modules with lm
. lmv
gives you version number and date information. lmf
gives you the full path. You can filter for a specific module by appending m modulename
. to any of the commands before.
How can I see to which module an object belongs?
That's not possible. Why? I have no reference, so let's make an educated guess.
a) tracking the DLL of every small object would add at least a pointer size overhead. That might be 8 bytes for a 4 byte int
.
b) which DLL would you track? There are always several DLLs on the call stack. One module calls the other, which calls the next. Finally, you might always end up somewhere in a Microsoft DLL, because that's where strings, ints and a lot of stuff comes from. You don't want that. On the other extreme, the executable is the main reason why memory is allocated in the first place. So, it wouldn't exactly be simple to figure out which assemblies to track and which assemblies you don't want in that list.
c) Looking at the call stack is quite an expensive operation. That's why throwing a lot of exceptions makes your application slow.
All in all, I'd say it's not feasible to record a module to each object.
The closest I can think of that has been implemented is Heap Tagging by DLL but that works with the Windows Heap Manager, which .NET doesn't use. Also, you just know which heap belongs to which DLL, not the objects.
loading debugging symbols: how do I do that?
Two steps should usually be sufficient:
.symfix
.sympath+ C:\some\directory
For more details, see How to set up symbols, which explains more details.
some "*.pdb" files
Not some. Use all.
C:\Temp_Folder\*
You don't need to use wildcards. Just specify the directory.
the modules stay deferred
That's wanted. Loading symbols is slow. They will be loaded when needed. If you want to load them now, use ld *
and get yourself a coffee while waiting.
might reveal a lot of information.
Sure. With debugging, you can get tons of information. You can have a look at everything. However, it's always good to know what you're looking for, when you have a haystack in front of you. That's still unclear to me. Why are you debugging? What are you looking for?