问题
I'm currently working in a memory issue on a .NET application, I'm debugging the Issue using Windbg I have come across to what the memory issue is, but during the investigation !do
command is getting me the object which has a content that is excessive large BUT the Content that gets displayed by the command is truncated, Is there a way that I can get the Content in its entirely from the !do
command?
The result of the command looks something like this:
0:000> !do [Address]
Name: System.Byte[]
MethodTable: ...
EEClass: ...
Size: 1048600(0x100018) bytes
Array: Rank 1, Number of elements 1048576, Type Byte
Content: [This is the content that its getting truncated]
Fields:
None
回答1:
Since you have a byte
array you can use db
to dump out the raw memory. I created a byte
array with values 0, 1, 2, ... 2000 and dumped it out:
0:000> !do 0x020a3560 Name: System.Byte[] MethodTable: 73504588 EEClass: 7319229c Size: 2012(0x7dc) bytes Array: Rank 1, Number of elements 2000, Type Byte Content: ................................ !"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~. Fields: None
0:000> db 0x020a3560 0x020a3560+07dc 020a3560 88 45 50 73 d0 07 00 00-00 01 02 03 04 05 06 07 .EPs............ 020a3570 08 09 0a 0b 0c 0d 0e 0f-10 11 12 13 14 15 16 17 ................ 020a3580 18 19 1a 1b 1c 1d 1e 1f-20 21 22 23 24 25 26 27 ........ !"#$%&' 020a3590 28 29 2a 2b 2c 2d 2e 2f-30 31 32 33 34 35 36 37 ()*+,-./01234567 020a35a0 38 39 3a 3b 3c 3d 3e 3f-40 41 42 43 44 45 46 47 89:;?@ABCDEFG 020a35b0 48 49 4a 4b 4c 4d 4e 4f-50 51 52 53 54 55 56 57 HIJKLMNOPQRSTUVW 020a35c0 58 59 5a 5b 5c 5d 5e 5f-60 61 62 63 64 65 66 67 XYZ[\]^_`abcdefg 020a35d0 68 69 6a 6b 6c 6d 6e 6f-70 71 72 73 74 75 76 77 hijklmnopqrstuvw 020a35e0 78 79 7a 7b 7c 7d 7e 7f-80 81 82 83 84 85 86 87 xyz{|}~......... 020a35f0 88 89 8a 8b 8c 8d 8e 8f-90 91 92 93 94 95 96 97 ................ ...(snip)...
The first 4 bytes are the method table (73504588), and the next 4 bytes are the length of the array (0x07D0, or 0n2000). Then all the bytes after that are the data.
回答2:
The answer by Patrick is ok for Byte[] or other simple types. If you need the same for reference types, try !da
of SOS
or !mdt
of the SOSEX
extension.
First, let's see how !da
works:
0:077> *** Get method table to be specific about the object
0:077> !dumpheap -stat -type PointF[]
total 290 objects
Statistics:
MT Count TotalSize Class Name
7ae3a114 290 8360 System.Drawing.PointF[]
Total 290 objects
0:077> *** Get individual arrays
0:077> !dumpheap -mt 7ae3a114
Address MT Size
3be693a4 7ae3a114 28
3be69400 7ae3a114 28
...
total 290 objects
Statistics:
MT Count TotalSize Class Name
7ae3a114 290 8360 System.Drawing.PointF[]
Total 290 objects
0:077> *** Pick one for demo purposes. Output is not that useful.
0:077> !do 3be693a4
Name: System.Drawing.PointF[]
MethodTable: 7ae3a114
EEClass: 7adeb1cc
Size: 28(0x1c) bytes
Array: Rank 1, Number of elements 2, Type VALUETYPE
Element Type: System.Drawing.PointF
Fields:
None
0:077> *** Dump contents of the array
0:077> !da 3be693a4
Name: System.Drawing.PointF[]
MethodTable: 7ae3a114
EEClass: 7adeb1cc
Size: 28(0x1c) bytes
Array: Rank 1, Number of elements 2, Type VALUETYPE
Element Methodtable: 7ae3c3ac
[0] 3be693ac
[1] 3be693b4
Now, you typically want more details about the two objects in the array. You could fiddle around with the .foreach
command, but there's no -short
option, so go the simpler way using !mdt
:
0:077> .load D:\debug\Extensions\sosex\4\32\sosex.dll
0:077> !mdt -e:2 3be693a4
3be693a4 (System.Drawing.PointF[], Elements: 2, ElementMT=7ae3c3ac)
[0] (System.Drawing.PointF) VALTYPE (MT=7ae3c3ac, ADDR=3be693ac)
x:0.000000 (System.Single)
y:-1.000000 (System.Single)
[1] (System.Drawing.PointF) VALTYPE (MT=7ae3c3ac, ADDR=3be693b4)
x:1917.000000 (System.Single)
y:22.000000 (System.Single)
increase depth
Update: PointF was not the best example, because it is also a value type, but it's similar for reference types.
来源:https://stackoverflow.com/questions/25435949/in-windbg-how-to-get-the-whole-content-from-do-command