는 배열에 생성되는 방법에 해당하는 IL를 덤프하는 한 가지 방법.
첫째, 당신이하고있는 방법을 얻을 수 !clrstack
를 사용합니다. 내 경우에는 내가에있어 Main
방법 더미 응용 프로그램 :
0:000> !name2ee ConsoleApplication4!ConsoleApplication4.Program.Main
Module: 00282eac
Assembly: ConsoleApplication4.exe
Token: 0600013c
MethodDesc: 00283dbc
Name: ConsoleApplication4.Program.Main(System.String[])
JITTED Code Address: 00320050
:
0:000> !clrstack
OS Thread Id: 0x7d0 (0)
Child SP IP Call Site
0016f094 758dc42d [HelperMethodFrame: 0016f094]
0016f120 003200af ConsoleApplication4.Program.Main(System.String[]) [c:\Users\smt\Documents\Visual Studio 2012\Projects\ConsoleApplication4\Program.cs @ 215]
0016f2bc 743b3de2 [GCFrame: 0016f2bc]
다음 사용 !name2ee
이 방법의 방법 내림차순 (다음 명령이 필요)를 얻을 수 이제
는 방법의 IL 덤프 : 유형 System.Single
의 새로운 배열이 생성되고 있음을 당신은 라인 IL_000f에 볼 수 있습니다
static void Main(string[] args)
{
List<float[]> arrays = new List<float[]>();
while (true)
{
float[] f = new float[Int32.MaxValue];
arrays.Add(f);
}
Console.ReadKey();
}
:
비교를 위해
0:000> !dumpil 00283dbc
ilAddr = 002d4bc4
IL_0000: nop
IL_0001: newobj class [mscorlib]System.Collections.Generic.List`1<?????? ??????n?.::.ctor
IL_0006: stloc.0
IL_0007: br.s IL_001e
IL_0009: nop
IL_000a: ldc.i4 2147483647
IL_000f: newarr System.Single
IL_0014: stloc.1
IL_0015: ldloc.0
IL_0016: ldloc.1
IL_0017: callvirt class [mscorlib]System.Collections.Generic.List`1<?????? ??????N?.::Add
IL_001c: nop
IL_001d: nop
IL_001e: ldc.i4.1
IL_001f: stloc.2
IL_0020: br.s IL_0109
,이 C#에서 내 방법입니다 .
배열을 만드는 실제 원시 메서드에 전달되는 인수를 해독 할 수 없기 때문에이 길을 건너갔습니다. 이 시점에서 kb
를 실행하면 예외가 발생합니다 : 1 차원 배열을 생성
0:000> kb
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0016efa4 74502a42 e0434352 00000001 00000005 KERNELBASE!RaiseException+0x58
0016f048 745d55ef 00000000 bc1d0b3d 0016f10c clr!RaiseTheExceptionInternalOnly+0x276
0016f078 7464ae51 bc1d0a7d 0016f150 00000000 clr!UnwindAndContinueRethrowHelperAfterCatch+0x83
0016f118 003200af 00000000 02202480 00000000 clr!JIT_NewArr1+0x1af
0016f138 743b3de2 00720198 0016f198 743c3315 0x3200af
0016f144 743c3315 0016f1dc 0016f188 74502c66 clr!CallDescrWorkerInternal+0x34
...
당신은 clr!JIT_NewArr1
가 호출되는 것을 볼 수 있습니다. 그렇게하려면 it needs the type and the size. ecx
어떻게 든 System.Single
의 형식 정보에 매핑 732a30e2
를 가져옵니다,
0:000> !u 003200AF
...
003200a0 b9e2302a73 mov ecx,offset mscorlib_ni+0x30e2 (732a30e2)
003200a5 baffffff7f mov edx,7FFFFFFFh
003200aa e89121f5ff call 00272240 (JitHelp: CORINFO_HELP_NEWARR_1_VC)
>>> 003200af 8945e8 mov dword ptr [ebp-18h],eax
003200b2 8b45e8 mov eax,dword ptr [ebp-18h]
003200b5 8945f0 mov dword ptr [ebp-10h],eax
...
당신이 볼 수 있듯이,하지만 난 ... 어떻게
을 알아낼 수 없습니다 : 이러한 인수는 각각
ecx
및
edx
에 복사
실제로 배열 유형이 ECX로 전달됩니다. 그러나 일반 메타 데이터 토큰이 아니라 '메타 데이터 토큰에 대한 핸들'입니다. 이것은 JIT에 의해 생성됩니다. 핸들에서 원래 메타 데이터 토큰으로 이동하는 방법을 알지 못합니다. 오히려 IL이 존재하기 때문에 어레이 유형을 식별하기 위해 IL을 볼 수 있습니다. – Dono