I have an OutOfMemoryException and I'd like to analyze the size and the type of the array which shall be created.
I have created a demo purpose dump for that situation and I'm able to get the following information:
0:000> !pe
Exception object: 023f389c
Exception type: System.OutOfMemoryException
Message: <none>
InnerException: <none>
StackTrace (generated):
SP IP Function
0015EE44 0099007F OOM2!OOM2.Program.Main()+0xf
StackTraceString: <none>
HResult: 8007000e
0:000> !u 0099007F
Normal JIT generated code
OOM2.Program.Main()
Begin 00990070, size 22
00990070 baffffff7f mov edx,7FFFFFFFh
00990075 b90241a478 mov ecx,offset mscorlib_ni+0x4102 (78a44102)
0099007a e8192194ff call 002d2198 (JitHelp: CORINFO_HELP_NEWARR_1_VC)
>>> 0099007f 8bc8 mov ecx,eax
...
So I can see that a new array is created and the size is 7FFFFFFF, which is 2 billion items. (Please ignore the fact that you can't even create a byte[] of that size in a 32 bit .NET application, so in this example the type would probably not matter at all.)
I have now read that the type of the array is in the ECX register, but unfortunately mscorlib_ni+0x4102 (78a44102) isn't very helpful.
I have tried !mln, !mdt and even unrealistic !ip2mt, but none of them displays the expected byte or byte[] output. Is there a way of getting the type from that native image of mscorlib?
One way to do it is to dump the IL corresponding to the method that the array is being created in.
First, use
!clrstackto get the method you're in. In my case I'm in a dummy app in theMainmethod:Next use
!name2eeto get the method desc of this method (the next command needs it):Now, dump the IL of the method:
For comparison, this is my method in C#:
You can see on line IL_000f that a new array of type
System.Singleis being created.I went down this road because I can't decipher the argument being passed to the actual native method that creates the array. If you run
kbat the point the exception is thrown:You can see that
clr!JIT_NewArr1is being called, which creates a one-dimensional array. To do that, it needs the type and the size. These arguments are copied intoecxandedx, respectively:As you can see,
ecxgets732a30e2, which somehow maps to the type information forSystem.Single, but I can't figure out how...