时间:2021-07-01 10:21:17 帮助过:25人阅读
3、还是跟以前调试一样,我们用Windbg打开编译后的EXE文件。
Opened log file ‘d:\log\mem11.txt‘ 0:000> sxe ld:clrjit 0:000> g (ad0.a2c): Unknown exception - code 04242420 (first chance) ModLoad: 6f290000 6f30d000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll eax=00000000 ebx=00000000 ecx=011737a4 edx=08000000 esi=7ffde000 edi=001be8d0 eip=778f70b4 esp=001be7e8 ebp=001be83c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 778f70b4 c3 ret 0:000> .loadby sos clr 0:000> !dumpdomain ... -------------------------------------- Domain 1: 00334d38 LowFrequencyHeap: 0033518c HighFrequencyHeap: 003351d4 StubHeap: 0033521c Stage: OPEN SecurityDescriptor: 00336908 ... Assembly: 0038fb80 [D:\bin\MemoryGen.exe] ClassLoader: 0038fc48 SecurityDescriptor: 0038f820 Module Name 01172edc D:\bin\MemoryGen.exe 0:000> !dumpmodule -mt 01172edc Name: D:\bin\MemoryGen.exe Attributes: PEFile Assembly: 0038fb80 LoaderHeap: 00000000 TypeDefToMethodTableMap: 01170038 TypeRefToMethodTableMap: 01170048 MethodDefToDescMap: 01170090 FieldDefToDescMap: 011700bc MemberRefToDescMap: 00000000 FileReferencesMap: 011700d0 AssemblyReferencesMap: 011700d4 MetaData start address: 0121223c (1836 bytes) Types defined in this module MT TypeDef Name ------------------------------------------------------------------------------ 011737b8 0x02000003 WindbugDemo.MemoryGen Types referenced in this module MT TypeRef Name ------------------------------------------------------------------------------ 682e41b8 0x02000001 System.Object 0:000> !dumpmt -md 011737b8 EEClass: 011712d4 Module: 01172edc Name: WindbugDemo.MemoryGen mdToken: 02000003 File: D:\bin\MemoryGen.exe BaseSize: 0xc ComponentSize: 0x0 Slots in VTable: 6 Number of IFaces in IFaceMap: 0 -------------------------------------- MethodDesc Table Entry MethodDe JIT Name 681c952c 67ee612c PreJIT System.Object.ToString() 681dec30 67ee6134 PreJIT System.Object.Equals(System.Object) 681de860 67ee6154 PreJIT System.Object.GetHashCode() 681de2a0 67ee6168 PreJIT System.Object.Finalize() 0117c015 011737b0 NONE WindbugDemo.MemoryGen..ctor() 0117c011 011737a4 NONE WindbugDemo.MemoryGen.Main(System.String[]) 0:000> !bpmd -md 011737a4 MethodDesc = 011737a4 Adding pending breakpoints... sxe -c "!HandleCLRN" clrn 0:000> g (ad0.a2c): CLR notification exception - code e0444143 (first chance) JITTED MemoryGen!WindbugDemo.MemoryGen.Main(System.String[]) Setting breakpoint: bp 011E0099 [WindbugDemo.MemoryGen.Main(System.String[])] bp 011E0099 g Breakpoint 0 hit eax=00000000 ebx=001bf33c ecx=01602198 edx=00000000 esi=01602198 edi=001bf288 eip=011e0099 esp=001bf238 ebp=001bf298 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 011e0099 90 nop 0:000> !u 011737a4 Normal JIT generated code WindbugDemo.MemoryGen.Main(System.String[]) Begin 011e0050, size 1a9 *** WARNING: Unable to verify checksum for MemoryGen.exe d:\source\03MemoryGen\MemoryGen.cs @ 42: 011e0050 55 push ebp 011e0051 8bec mov ebp,esp 011e0053 57 push edi 011e0054 56 push esi 011e0055 83ec58 sub esp,58h ... d:\source\03MemoryGen\MemoryGen.cs @ 57: 011e01cd 33d2 xor edx,edx 011e01cf 8955b8 mov dword ptr [ebp-48h],edx ... 0:000> bp 011e01cd 0:000> !bpmd mscorlib.dll System.GC.Collect Found 4 methods in module 67ee1000... MethodDesc = 67f709ec MethodDesc = 67f709f8 MethodDesc = 67f70a04 MethodDesc = 67f70a10 Setting breakpoint: bp 681BEF6C [System.GC.Collect(Int32, System.GCCollectionMode, Boolean)] bp 681BEF6C Setting breakpoint: bp 688A5B80 [System.GC.Collect(Int32, System.GCCollectionMode)] bp 688A5B80 Setting breakpoint: bp 688A5B2D [System.GC.Collect()] bp 688A5B2D Setting breakpoint: bp 688A5B10 [System.GC.Collect(Int32)] bp 688A5B10 Adding pending breakpoints... sxe -c "!HandleCLRN" clrn 0:000> g
4、在【release = null;】的这句代码加上断点,对象赋空后,GC操作后,我们可以再查阅一个该对象的引用。!bpmd mscorlib.dll System.GC.Collect命令,表示当我们显式调用GC.Collect时,Windbg能中止程序,进入调试命令。
5、当程序中断时,调用!clrstack -a命令,观察一下是否是由于大对象(>90)这个if分支引起的中断,否则我们就执行dumpgen(需要加载sosex.dll调试扩展)
0:000> !clrstack -a OS Thread Id: 0xa2c (0) Child SP IP Call Site 001bf208 688a5b2d System.GC.Collect() 001bf20c 011e01d8 [InlinedCallFrame: 001bf20c] 001bf238 011e01d8 WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 59] PARAMETERS: args (0x001bf28c) = 0x01602198 LOCALS: 0x001bf25c = 0x016021a8 0x001bf258 = 0x016021d8 0x001bf288 = 0x00000064 0x001bf254 = 0x01624ab0 0x001bf250 = 0x016022d8 0x001bf280 = 0x65280834 0x001bf27c = 0x00000001 0:000> !do 0x016022d8 Name: WindbugDemo.MemoryApply MethodTable: 011745e8 EEClass: 01171360 Size: 24(0x18) bytes File: D:\bin\MemoryGen.exe Fields: MT Field Offset Type VT Attr Value Name 682e6d34 4000001 c System.Byte[] 0 instance 016022f0 AllocateByte 682f05f4 4000002 4 System.Int64 1 instance 637300683725008226 <Ticks>k__BackingField 682e560c 4000003 10 System.Int32 1 instance 69 <MemSize>k__BackingField 0:000> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x01601018 generation 1 starts at 0x0160100c generation 2 starts at 0x01601000 ephemeral segment allocation context: (0x01624c54, 0x01625bf4) segment begin allocated size 01600000 01601000 01625bf4 0x24bf4(150516) Large object heap starts at 0x02601000 segment begin allocated size 02600000 02601000 0261da58 0x1ca58(117336) Total Size: Size: 0x4164c (267852) bytes. ------------------------------ GC Heap Size: Size: 0x4164c (267852) bytes. 0:000> .load sosex.dll 0:000> !dumpgen 0 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 016021a8 01174638 32 System.Collections.Generic.Queue`1[[WindbugDemo.MemoryApply, MemoryGen]] 016022d8 011745e8 24 WindbugDemo.MemoryApply 01615abc 011745e8 24 WindbugDemo.MemoryApply 01624ab0 011745e8 24 WindbugDemo.MemoryApply 4 objects, 104 bytes 0:000> !dumpgen 1 -type WindbugDemo.MemoryApply 0 objects, 0 bytes 0:000> !dumpgen 2 -type WindbugDemo.MemoryApply 0 objects, 0 bytes 0:000> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x01601018 generation 1 starts at 0x0160100c generation 2 starts at 0x01601000 ephemeral segment allocation context: (0x01624c54, 0x01625bf4) segment begin allocated size 01600000 01601000 01625bf4 0x24bf4(150516) Large object heap starts at 0x02601000 segment begin allocated size 02600000 02601000 0261da58 0x1ca58(117336) Total Size: Size: 0x4164c (267852) bytes. ------------------------------ GC Heap Size: Size: 0x4164c (267852) bytes.
运行 !do命令,观察0x01601018对象,跟eeheap命令输出的内存段相比,的确位于0代内存上。用!dumpgen 0 -type WindbugDemo.MemoryApply命令,输出结果也验证了我们的猜想。
6、运行g命令,再次启动程序。
0:000> g Breakpoint 4 hit eax=001bf418 ebx=001bf33c ecx=01615abc edx=00000000 esi=0036d090 edi=001bf20c eip=688a5b2d esp=001bf208 ebp=001bf230 iopl=0 nv up ei pl nz ac po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212 mscorlib_ni+0x9c5b2d: 688a5b2d 6a02 push 2 0:000> !clrstack -a OS Thread Id: 0xa2c (0) Child SP IP Call Site 001bf208 688a5b2d System.GC.Collect() 001bf20c 011e01d8 [InlinedCallFrame: 001bf20c] 001bf238 011e01d8 WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 59] PARAMETERS: args (0x001bf28c) = 0x01602198 LOCALS: 0x001bf25c = 0x016021a8 0x001bf258 = 0x016021d8 0x001bf288 = 0x00000043 0x001bf254 = 0x01624be0 0x001bf250 = 0x01615abc 0x001bf280 = 0x13c9dc2e 0x001bf27c = 0x00000001 001bf418 68f52552 [GCFrame: 001bf418] 0:000> !dumpgen 0 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 01624be0 011745e8 24 WindbugDemo.MemoryApply 1 object, 24 bytes 0:000> !dumpgen 1 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 016021a8 01174638 32 System.Collections.Generic.Queue`1[[WindbugDemo.MemoryApply, MemoryGen]] 016022d8 011745e8 24 WindbugDemo.MemoryApply 01615abc 011745e8 24 WindbugDemo.MemoryApply 01624ab0 011745e8 24 WindbugDemo.MemoryApply 4 objects, 104 bytes 0:000> !dumpgen 2 -type WindbugDemo.MemoryApply 0 objects, 0 bytes
我们发现原来位于0代的内存对象,已经被系统提升至了1代。而2代内存对象没有。
7、运行g命令,让程序继续执行,当程序再次中断时
0:000> g Breakpoint 1 hit eax=00000001 ebx=001bf33c ecx=016159b8 edx=00000000 esi=001bf270 edi=001bf280 eip=011e01cd esp=001bf238 ebp=001bf298 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 011e01cd 33d2 xor edx,edx 0:000> !clrstack -a OS Thread Id: 0xa2c (0) Child SP IP Call Site 001bf238 011e01cd WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 57] PARAMETERS: args (0x001bf28c) = 0x01602198 LOCALS: 0x001bf25c = 0x016021a8 0x001bf258 = 0x016021d8 0x001bf288 = 0x00000073 0x001bf254 = 0x016352d4 0x001bf250 = 0x01624ab0 0x001bf280 = 0x387ad227 0x001bf27c = 0x00000000 001bf418 68f52552 [GCFrame: 001bf418] 0:000> !do 0x387ad227 <Note: this object has an invalid CLASS field> Invalid object 0:000> !do 0x01624ab0 Name: WindbugDemo.MemoryApply MethodTable: 011745e8 EEClass: 01171360 Size: 24(0x18) bytes File: D:\bin\MemoryGen.exe Fields: MT Field Offset Type VT Attr Value Name 682e6d34 4000001 c System.Byte[] 0 instance 026053a8 AllocateByte 682f05f4 4000002 4 System.Int64 1 instance 637300683735304244 <Ticks>k__BackingField 682e560c 4000003 10 System.Int32 1 instance 100 <MemSize>k__BackingField 0:000> !gcroot 0x01624ab0 Thread a2c: 001bf238 011e01cd WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 57] ebp+48: 001bf250 -> 01624ab0 WindbugDemo.MemoryApply 001bf238 011e01cd WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 57] ebp+5c: 001bf23c -> 01624ab0 WindbugDemo.MemoryApply Found 2 unique roots (run ‘!GCRoot -all‘ to see all roots).
这时,我们发现,是因为出队的这个对象尺寸大于90K,那么对象会被置为空,查看GCroot,这时的对象尚未被回收,我们继续运行g命令。
0:000> g Breakpoint 4 hit eax=001bf418 ebx=001bf33c ecx=01624be0 edx=00000000 esi=0036d090 edi=001bf20c eip=688a5b2d esp=001bf208 ebp=001bf230 iopl=0 nv up ei pl nz ac po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212 mscorlib_ni+0x9c5b2d: 688a5b2d 6a02 push 2 0:000> !clrstack -a OS Thread Id: 0xa2c (0) Child SP IP Call Site 001bf208 688a5b2d System.GC.Collect() 001bf20c 011e01d8 [InlinedCallFrame: 001bf20c] 001bf238 011e01d8 WindbugDemo.MemoryGen.Main(System.String[]) [d:\source\03MemoryGen\MemoryGen.cs @ 59] PARAMETERS: args (0x001bf28c) = 0x01602198 LOCALS: 0x001bf25c = 0x016021a8 0x001bf258 = 0x016021d8 0x001bf288 = 0x00000056 0x001bf254 = 0x016355cc 0x001bf250 = 0x01624be0 0x001bf280 = 0x1abedf72 0x001bf27c = 0x00000001 001bf418 68f52552 [GCFrame: 001bf418] 0:000> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x016355c0 generation 1 starts at 0x016351bc generation 2 starts at 0x01601000 ephemeral segment allocation context: (0x0163576c, 0x016375cc) segment begin allocated size 01600000 01601000 016375cc 0x365cc(222668) Large object heap starts at 0x02601000 segment begin allocated size 02600000 02601000 0264ebc0 0x4dbc0(318400) Total Size: Size: 0x8418c (541068) bytes. ------------------------------ GC Heap Size: Size: 0x8418c (541068) bytes. 0:000> !do 0x01624ab0 Name: WindbugDemo.MemoryApply MethodTable: 011745e8 EEClass: 01171360 Size: 24(0x18) bytes File: D:\bin\MemoryGen.exe Fields: MT Field Offset Type VT Attr Value Name 682e6d34 4000001 c System.Byte[] 0 instance 026053a8 AllocateByte 682f05f4 4000002 4 System.Int64 1 instance 637300683735304244 <Ticks>k__BackingField 682e560c 4000003 10 System.Int32 1 instance 100 <MemSize>k__BackingField 0:000> !FinalizeQueue SyncBlocks to be cleaned up: 0 Free-Threaded Interfaces to be released: 0 MTA Interfaces to be released: 0 STA Interfaces to be released: 0 ---------------------------------- generation 0 has 0 finalizable objects (00376d20->00376d20) generation 1 has 0 finalizable objects (00376d20->00376d20) generation 2 has 6 finalizable objects (00376d08->00376d20) Ready for finalization 0 objects (00376d20->00376d20) Statistics for all finalizable objects (including all objects ready for finalization): MT Count TotalSize Class Name 682e7048 1 20 Microsoft.Win32.SafeHandles.SafePEFileHandle 682e6068 1 20 Microsoft.Win32.SafeHandles.SafeFileHandle 682dc234 1 20 Microsoft.Win32.SafeHandles.SafeFileMappingHandle 682dc1e4 1 20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle 682e76d0 1 44 System.Threading.ReaderWriterLock 682e4960 1 52 System.Threading.Thread Total 6 objects 0:000> !gcroot 0x01624ab0 Found 0 unique roots (run ‘!GCRoot -all‘ to see all roots). 0:000> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x016355c0 generation 1 starts at 0x016351bc generation 2 starts at 0x01601000 ephemeral segment allocation context: (0x0163576c, 0x016375cc) segment begin allocated size 01600000 01601000 016375cc 0x365cc(222668) Large object heap starts at 0x02601000 segment begin allocated size 02600000 02601000 0264ebc0 0x4dbc0(318400) Total Size: Size: 0x8418c (541068) bytes. ------------------------------ GC Heap Size: Size: 0x8418c (541068) bytes. 0:000> !dumpgen 0 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 016355cc 011745e8 24 WindbugDemo.MemoryApply 1 object, 24 bytes 0:000> !dumpgen 1 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 016352d4 011745e8 24 WindbugDemo.MemoryApply 1 object, 24 bytes 0:000> !dumpgen 2 -type WindbugDemo.MemoryApply Object MT Size Name --------------------------------------------------- 016021a8 01174638 32 System.Collections.Generic.Queue`1[[WindbugDemo.MemoryApply, MemoryGen]] 01624ab0 011745e8 24 WindbugDemo.MemoryApply 01624be0 011745e8 24 WindbugDemo.MemoryApply 3 objects, 80 bytes 0:000> .logclose Closing open log file d:\log\mem11.txt
这时,我们发现原来的1代内存已经被提升至第2代了。
Windbg探索之.NET内存管理方式
标签:内存分配 address jit shc ram null apply reading 编译