windbg - System.TypeLoadException 예외 분석 사례
이상하군요, 겉으로는 응용 프로그램이 잘 동작하는데 특정 타입의 기능이 먹통입니다. 다행히, JIT 컴파일 내역을 로그로 남기는 기능을 Profiler에 구현해 두었는데, 그것을 통해 System.TypeLoadException 예외가 발생한 것을 알게 되었습니다.
좀 더 구체적인 것은, 해당 예외가 발생한 곳에 예외 처리를 해 상세한 오류 메시지를 남기면 되는데요, 그래도 혹시 현재 상태에서 풀 메모리 덤프를 남겨 원인을 밝힐 수도 있지 않을까요?
운이 좋다면, 결국 특정 스레드에서 예외가 발생한 것이므로 해당 스레드의 스택에 아직 예외가 있는 경우 !threads 명령어로 확인하는 것이 가능합니다.
0:030> !threads
ThreadCount: 11
UnstartedThread: 0
BackgroundThread: 11
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
6 1 1730 01cce0f8 28220 Preemptive 00000000:00000000 015d4188 0 Ukn
18 2 2cd8 01d3b0e8 2b220 Preemptive 0E007FD4:00000000 015d4188 0 MTA (Finalizer)
20 3 29cc 1c386b20 102a220 Preemptive 00000000:00000000 015d4188 0 MTA (Threadpool Worker)
21 4 2cb4 1c708ed8 21220 Preemptive 00000000:00000000 015d4188 0 Ukn
22 5 888 1da5b758 1020220 Preemptive 00000000:00000000 015d4188 0 Ukn (Threadpool Worker)
23 6 bcc 1db17800 1029220 Preemptive 0A2D51CC:00000000 015d4188 0 MTA (Threadpool Worker)
24 7 380 1ddb5918 1029220 Preemptive 061B44FC:00000000 015d4188 0 MTA (Threadpool Worker)
26 8 1ed0 2109a700 1029220 Preemptive 02063BEC:00000000 015d4188 0 MTA (Threadpool Worker)
27 9 175c 1e90e278 1029220 Preemptive 01FDD604:00000000 015d4188 0 MTA (Threadpool Worker)
3 10 9d4 213922c0 20220 Preemptive 0E0CA490:00000000 015d4188 0 Ukn
29 11 2e5c 21263048 1029220 Preemptive 00000000:00000000 015d4188 0 MTA (Threadpool Worker)
하지만, 이미 예외가 발생 후 시간이 지나서 스택에 남아 있지 않은 상태군요. ^^ 그렇다면 그다음 후보군으로 GC Heap을 선택할 수 있습니다. 다행히 TypeLoadException은 많은 인스턴스가 생성되는 유형은 아니므로 몇 개 없을 것입니다.
0:030> !dumpheap -type System.TypeLoadException
Address MT Size
01edd214 1ba07334 100
Statistics:
MT Count TotalSize Class Name
1ba07334 1 100 System.TypeLoadException
Total 1 objects
1개 있군요. ^^ 곧바로 덤프한 후,
0:030> !do 01edd214
Name: System.TypeLoadException
MethodTable: 1ba07334
EEClass: 1b9f6850
Size: 100(0x64) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
1ab1fe08 40002a4 4 System.String 0 instance 00000000 _className
1ba032a4 40002a5 8 ...ection.MethodBase 0 instance 00000000 _exceptionMethod
1ab1fe08 40002a6 c System.String 0 instance 00000000 _exceptionMethodString
1ab1fe08 40002a7 10 System.String 0 instance 01edd31c _message
1afd6a64 40002a8 14 ...tions.IDictionary 0 instance 00000000 _data
1afd059c 40002a9 18 System.Exception 0 instance 00000000 _innerException
1ab1fe08 40002aa 1c System.String 0 instance 00000000 _helpURL
1ab167d8 40002ab 20 System.Object 0 instance 01edd4c8 _stackTrace
1ab167d8 40002ac 24 System.Object 0 instance 01edd504 _watsonBuckets
1ab1fe08 40002ad 28 System.String 0 instance 00000000 _stackTraceString
1ab1fe08 40002ae 2c System.String 0 instance 00000000 _remoteStackTraceString
1ab1ca20 40002af 3c System.Int32 1 instance 0 _remoteStackIndex
1ab167d8 40002b0 30 System.Object 0 instance 00000000 _dynamicMethods
1ab1ca20 40002b1 40 System.Int32 1 instance -2146233054 _HResult
1ab1fe08 40002b2 34 System.String 0 instance 00000000 _source
1ab1e64c 40002b3 44 System.IntPtr 1 instance 0 _xptrs
1ab1ca20 40002b4 48 System.Int32 1 instance -532462766 _xcode
1ab1e814 40002b5 4c System.UIntPtr 1 instance 0 _ipForWatsonBuckets
1d35cefc 40002b6 38 ...ializationManager 0 instance 01edd278 _safeSerializationManager
1ab167d8 40002a3 84 System.Object 0 shared static s_EDILock
>> Domain:Value 015d4188:NotInit 1c6ff840:NotInit <<
1ab1fe08 40006ed 50 System.String 0 instance 01edd0fc ClassName
1ab1fe08 40006ee 54 System.String 0 instance 01edd174 AssemblyName
1ab1fe08 40006ef 58 System.String 0 instance 00000000 MessageArg
1ab1ca20 40006f0 5c System.Int32 1 instance 8344 ResourceId
string 타입의 _message 속성을 다시 덤프하면 구체적인 오류 메시지가 나옵니다.
0:030> !do 01edd31c
Name: System.String
MethodTable: 1ab1fe08
EEClass: 1ab3e3e4
Size: 414(0x19e) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: Inheritance security rules violated by type: 'MyPackage.MyType'. Derived types must either match the security accessibility of the base type or be less accessible.
Fields:
MT Field Offset Type VT Attr Value Name
1ab1ca20 4000283 4 System.Int32 1 instance 200 m_stringLength
1ab1b1dc 4000284 8 System.Char 1 instance 49 m_firstChar
1ab1fe08 4000288 70 System.String 0 shared static Empty
>> Domain:Value 015d4188:NotInit 1c6ff840:NotInit <<
그렇군요, .NET 4.0의 보안 체계로,
.NET CLR4 보안 모델 - 1. "Security Level 2"란?
; https://www.sysnet.pe.kr/2/0/1680
발생한 것이어서, SecuritySafeCritical 특성을 부여하는 걸로 해결했습니다.
using System;
using System.IO;
using System.Security;
namespace MyPackage
{
[SecuritySafeCritical]
public class MyType
{
// ... [생략]...
}
}
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]