WinDBG Walkthrough - Dump Values Of DataSet or DataTable
This walkthrough is completely based on Johan's post WinDBG+SOS: Getting at the values in a DataTable. I have created this one to help me do the job in straightforward way next time I hit similar problem. Joan also offers few scripts for process automation - recommended. | by glennharper |
Customer Case Study
The customer complained about potential memory leak. Following the procedure described in Identifying Memory Leak With Process Explorer And Windbg we realized that we are dealing with static variable that grows in unlimited way. This assumption is based on the fact that after running !gcroot on the leaking type we get the following:
HANDLE(Strong): 23b1cd0:Root:0x12571730.....
After reviewing Tess' .NET Debugging Demos Lab 7: Memory Leak - Review we found the following which made us believe we are dealing with static variable:
DOMAIN(001CCE68):HANDLE(Strong) - Strong reference, Typically a static variable
To identify what this static variable is we needed to dump its values. The variable was a DataTable. I have not found a straightforward way of dumping contents of DataTable. This is the walkthrough that does the job.
Summary of steps
- Step 1. Dump DataTables
- Step 2. Dump DataTable
- Step 3. Dump columnCollection
- Step 4. Dump list object
- Step 5. Dump raw memory - dd command
- Step 6. Dump DataColumn
- Step 7. Dump storage
- Step 8. Dump values
- Step 9. Bonus - automation
Step 1. Dump DataTables
The objective of this step is identify all DataTable object and pick the one of the interest
0:000> !dumpdatatables
DataTable Rows Columns DataSet nextRowID ColumnCount
-----------------------------------------------------------------------------------------------
0x024dc948 0x024dcbc8 0x024dcdec 0x064f2400 1 2
0x025156b8 0x02515938 0x02515b5c 0x02515478 1 7
...
0x0e5b9ce4 0x0e5b9f64 0x0e5ba138 0x0e55a338 428 5
0x06510e54 0x065110d4 0x065112a8 0x064f2400 1,359 7
0x0e5778f0 0x0e577b70 0x0e577d44 0x0e55a338 1,359 7
0x0a55d270 0x0a55d4f0 0x0a55d6c4 0x06a62620 4,194,305 10
Total 61 DataTable objects
Step 2. Dump DataTable
The objective of this step is identifying the address of columnCollection of the DataTable.
0:000> !do
0x0a55d270 Name: System.Data.DataTable
...
0x176c1560 0x40003f2 0x18 CLASS instance 0x0a55d6c4 columnCollection
...
Step 3. Dump columnCollection
The objective of this step is identifying the address of list object of the columnCollection.
0:000> !do 0x0a55d6c4
Name: System.Data.DataColumnCollection
...
0x176c5ffc 0x4000377 0x8 CLASS instance 0x0a55d6f8 list
...
Step 4. Dump list object
The objective of this step is identifying the address of _items object.
0:000> !do 0x0a55d6f8
Name: System.Collections.ArrayList
...
0x79ba75ec 0x4000362 0x4 CLASS instance 0x0a55d710 _items
...
Step 5. Dump raw memory - dd command
The objective of this step is identifying addresses of DataColumn objects.
0:000> dd 0x0a55d710
0a55d710 01e5209c 00000010 79b92eec 0a55d854
0a55d720 0a55d8d4 0a55d954 0a55d9d4 0a55da54
0a55d730 0a55dad4 0a55db54 0a55dbd4 0a55dd74
Step 6. Dump DataColumn
The objective of this step is identifying the address of storage object.
!do 0a55d854
Name: System.Data.DataColumn
...
0x176c69e8 0x400036b 0x48 CLASS instance 0x0a55df40 storage
...
Step 7. Dump storage
The objective of this step is identifying address of value object.
0:000> !do 0x0a55df40
Name: System.Data.Common.Int32Storage
...
0x176ecc8c 0x4000729 0x10 CLASS instance 0x4dbd0030 values
...
Step 8. Dump values
The objective of this step is dumping the actual values, finally...
0:000> !do 0x4dbd0030
Name: System.Int32[]
...
Content: 8,388,608 items
Ouch, it is array.... !do -v will dump its values, but I am afraid it is not a good idea doing it for 8 million items here ;)
Step 9. Bonus - automation
The objective of this step is automate the process of dumping values (Step 8):
- Create a text file named dumparray and save it in WinDBG directory. The contents of the file are:
- .foreach ( o { !do ${$arg1} -v -short }) { !do ${o} }
- Run the following command in WinDBG to dump the values of the array
- $$>a< dumparray 0x4dbd0030
Related Materials
- Identifying Memory Leak With Process Explorer And Windbg
- Avoid Manipulating Passwords In Memory - It Is Easy To Reveal
This post is made with PracticeThis.com plugin for Windows Live Writer
Comments
- Anonymous
March 08, 2009
!dumpdatatables isn't available with SOS.dll for .net 2.0 externally as yet. I guess we need to do a!dumpheap -type System.Data.DataTableto get started - Anonymous
March 08, 2009
Good catch AtulGupta!Thanks for calling this out. - Anonymous
March 12, 2009
.NET NP .NET Profiler – a tool is designed to assist in troubleshooting issues such as slow performance - Anonymous
March 12, 2009
.NETNP.NETProfiler–atoolisdesignedtoassistintroubleshootingissuessuchasslowperf...