성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>windbg 사례 - .NET 예외가 발생한 시점의 오류 분석</h1> <p> 이상하게 특정 상황에서 <a target='tab' href='System.TypeInitializationException'>System.TypeInitializationException</a> 예외가 발생하는 현상이 나왔습니다. 다행히 항상 발생해서 다음과 같이 프로세스 덤프를 떠 상황을 살펴봤습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > procdump -ma -e 1 -f TypeInit* [...process id...] </pre> <br /> windbg에서 덤프 파일을 로드하고 sos 확장을 올린 후,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>.load C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\sos.dll</span> </pre> <br /> System.TypeInitializationException 예외가 발생한 스레드를 찾아,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>!threads</span> DBGHELP: mscorwks - public symbols d:\symbols\mscorwks.pdb\39E8C83B21A943B2B2DBC56A5E85676A1\mscorwks.pdb ThreadCount: 64 UnstartedThread: 0 BackgroundThread: 64 PendingThread: 0 DeadThread: 0 Hosted Runtime: no PreEmptive Lock ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception 14 1 3c4 00000000036a8580 1808228 Enabled 00000000c06ae3a0:00000000c06af788 0000000000128a60 0 MTA (Threadpool Worker) 18 2 15cc 00000000036b13a0 b228 Enabled 0000000080436ec8:0000000080437110 0000000000128a60 0 MTA (Finalizer) 19 3 197c 00000000047822b0 80a228 Enabled 0000000000000000:0000000000000000 0000000000128a60 0 MTA (Threadpool Completion Port) ...[생략]... <span style='color: blue; font-weight: bold'> 85 43 c34 000000000b326010 188b228 Enabled 0000000080851f98:0000000080853338 000000000493cc00 1 MTA (Threadpool Worker) System.TypeInitializationException (00000000c039d708)</span> 86 56 1230 000000000a54d010 880b228 Enabled 0000000080478468:0000000080479220 0000000000128a60 0 MTA (Threadpool Completion Port) ...[생략]... </pre> <br /> 대상 스레드로 문맥 전환을 하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>~85s</span> </pre> <br /> 예외를 조사했습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>!pe</span> Exception object: 00000000c039d708 Exception type: System.TypeInitializationException Message: The type initializer for 'TestLib.MyTestClass' threw an exception. InnerException: System.AccessViolationException, <span style='color: blue; font-weight: bold'>use !PrintException 00000000c039d4e8</span> to see more StackTrace (generated): SP IP Function 000000000946DFA0 0000000000000001 TestWebSite!TestLib.MyTestClass..ctor()+0x2 000000000946E070 0000064281C70533 TestWebSite!TestLib.TempWebPage.Page_Load(System.Object, System.EventArgs)+0x63 StackTraceString: <none> HResult: 80131534 </pre> <br /> 친절하게 InnerException을 살펴보라고 하는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>!PrintException 00000000c039d4e8</span> Exception object: 00000000c039d4e8 Exception type: System.AccessViolationException Message: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. InnerException: <none> StackTrace (generated): SP IP Function 000000000F25CAE0 0000000000000001 TestWebSite!TestLib.MyTestClass..cctor()+0x2 StackTraceString: <none> HResult: 80004003 </pre> <br /> 딱히 정보가 없습니다. 혹시나 해서 대상 메서드를 좀 더 조사해봤지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>!name2ee TestWebSite!TestLib.MyTestClass..cctor</span> Module: 00000642803f6008 (TestWebSite.DLL) Token: 0x0000000006000360 MethodDesc: <span style='color: blue; font-weight: bold'>0000064281cb8210</span> Name: TestLib.MyTestClass..cctor() Not JITTED yet. Use !bpmd -md 0000064281cb8210 to break on run. 0:085> <span style='color: blue; font-weight: bold'>!dumpmd 0000064281cb8210</span> Method Name: TestLib.MyTestClass..cctor() Class: 0000064281cd2c40 MethodTable: 0000064281cb8218 mdToken: 06000360 Module: 00000642803f6008 IsJitted: no CodeAddr: ffffffffffffffff 0:085> <span style='color: blue; font-weight: bold'>!dumpil 0000064281cb8210</span> ilAddr = 000000001000db65 IL_0000: ldc.i4.1 IL_0001: stsfld TestLib.MyTestClass::_isFirst IL_0006: ret </pre> <br /> 보는 바와 같이, JIT 컴파일되지도 않았기 때문에 System.AccessViolationException이 발생할만한 상황도 아니었고, 게다가 dumpil 명령어로 확인한 cctor의 코드는 어떤 포인터 연산도 포함하지 않았습니다. clrstack을 봐도 System.AccessViolationException 예외가 발생하기 바로 직전의 메서드는 확인할 수 없었고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>!clrstack</span> OS Thread Id: 0xc34 (85) Child-SP RetAddr Call Site 000000000946e070 0000064280bb5719 TestLib.TempWebPage.Page_Load(System.Object, System.EventArgs) 000000000946e0d0 0000064280bb56d4 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs) 000000000946e100 0000064280bb5675 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs) ...[생략]... 000000000946e570 000006428066a599 System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object) 000000000946e5c0 0000064280667178 System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest) 000000000946e630 000006427f5fcda2 System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32) </pre> <br /> Native 콜 스택 결과도 마찬가지였습니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:085> <span style='color: blue; font-weight: bold'>kv</span> Child-SP RetAddr : Args to Child : Call Site 00000000`0946a798 00000000`77d706af : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwWaitForSingleObject+0xa 00000000`0946a7a0 00000642`7f494b46 : 00000000`00001a0c 00000000`00000000 00000000`00000000 00000000`ffffffff : kernel32!WaitForSingleObjectEx+0x130 00000000`0946a840 00000642`7f494a4f : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : mscorwks!CLREvent::WaitEx+0x15a 00000000`0946a8a0 00000642`7f8ba79b : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : mscorwks!CLREvent::WaitEx+0x63 00000000`0946a950 00000642`7f8baa01 : 00000002`000003f0 00000000`00000000 00000000`00000006 00000000`0180b228 : mscorwks!Thread::WaitSuspendEventsHelper+0xdb 00000000`0946aa20 00000642`7f7af02c : 00000000`00000048 00000000`0b326010 00000002`000003f0 00000642`7f514eb0 : mscorwks!Thread::WaitSuspendEvents+0x11 00000000`0946aa50 00000642`7f9fb68e : ffffffff`fffffffe 00000642`7f55353b 00000000`00141950 00000000`0b326010 : mscorwks! ?? ::FNODOBFM::`string'+0x2170c 00000000`0946aaa0 00000642`7f966b38 : 00000000`0946abc0 00000000`00000000 00000000`00141950 00000000`00000006 : mscorwks!Thread::RareDisablePreemptiveGC+0x10e 00000000`0946ab40 00000642`7f96701a : 00000000`0b326010 00000642`7f53716c 00000000`0476afd0 00000000`0946c090 : mscorwks!Debugger::SendException+0x518 00000000`0946b110 00000642`7f8341ef : 00000000`036a65b8 00000000`0b326010 00000000`04e038e0 00000642`00000000 : mscorwks!Debugger::FirstChanceManagedException+0x2a 00000000`0946b170 00000642`7f4fe870 : 00000000`036a6580 00000000`0946c090 00000000`0946e070 00000000`00000000 : mscorwks! ?? ::FNODOBFM::`string'+0xa68cf 00000000`0946b3c0 00000642`7f4ffcff : 00000642`81c70532 00000642`81cd2e5c 00000000`0946ced0 00000000`0946c398 : mscorwks!ExceptionTracker::ProcessOSExceptionNotification+0x430 00000000`0946c280 00000000`77ee3d4d : 00000642`00000001 00000000`0946e070 00000000`0946ced0 00000000`00000000 : mscorwks!ProcessCLRException+0x19b 00000000`0946c320 00000000`77ee5857 : 00000000`00000001 00000000`00000001 00000000`0946ced0 00000000`0946dfa0 : ntdll!RtlpExecuteHandlerForException+0xd 00000000`0946c350 00000000`77ef2a3d : fffffadf`b37bfeb0 00000000`0946ca00 00000642`81cb8218 00000642`81cb8218 : ntdll!RtlDispatchException+0x1b4 00000000`0946ca00 00000000`77d4dce0 : 00000000`0b326010 00000642`81cb8218 00000000`e0434f4d 00000000`0b326010 : ntdll!KiUserExceptionDispatch+0x2d (TrapFrame @ 00000000`0946ce08) 00000000`0946cfa0 00000642`7f475c05 : 00000000`0b326010 00000642`81cb8218 00000000`e0434f4d 00000000`0b326010 : kernel32!RaiseException+0x5c 00000000`0946d070 00000642`7f8a5b57 : 00000000`c039d708 00000000`00000000 00000642`00000000 00000642`00000001 : mscorwks!RaiseTheExceptionInternalOnly+0x295 00000000`0946d140 00000642`7f8a6866 : 00002026`00000001 00000642`00000000 00009fca`5c79603c 00000000`0f355128 : mscorwks!RaiseTheException+0x57 00000000`0946d170 00000642`7f929d55 : 00000642`81cb8218 00000642`81cb8218 00000000`00000000 00000000`0a4010e0 : mscorwks!BStrFromString+0x66 00000000`0946d1a0 00000642`7f929d6b : 00000000`c039d708 00000000`0a4010e0 00000000`00000000 00000000`0a4010e0 : mscorwks!RealCOMPlusThrow+0x35 00000000`0946d210 00000642`7f80be5e : 00000642`81cb8218 00000642`81cb8218 00000000`00000000 00000000`0a4010e0 : mscorwks!RealCOMPlusThrow+0xb 00000000`0946d240 00000642`7f97f6f8 : 00000000`000001f0 00000642`81cb8218 00000000`00000191 00000642`803f7630 : mscorwks! ?? ::FNODOBFM::`string'+0x7e53e 00000000`0946dcf0 00000642`7f4d71f2 : 00000000`c00afea8 00000000`00000000 00000000`00000000 00000642`7f4e7d5e : mscorwks!MethodTable::CheckRunClassInitThrowing+0x68 00000000`0946dd30 00000642`7f4c9ebb : 00000000`c00b4188 00000000`00000000 00000000`00000000 00000000`0946e1e0 : mscorwks!MethodDesc::DoPrestub+0x192 00000000`0946dee0 00000642`7f5fcc87 : 00000000`808514e0 00000000`c0023820 00000000`8084d918 00000000`0b326010 : mscorwks!PreStubWorker+0x1eb 00000000`0946dfa0 00000642`81c70532 : 00000000`80851ec0 00000000`80851ed8 00000000`c0023820 00000000`c0023820 : mscorwks!ThePreStubAMD64+0x87 00000000`0946e070 00000642`80bb5719 : 00000000`8084d918 00000000`8084d918 00000000`c0023820 00000642`8080ff12 : 0x642`81c70532 00000000`0946e0d0 00000642`80bb56d4 : 00000000`8084d918 00000642`80b36250 00000000`8084d918 00000000`c0023820 : 0x642`80bb5719 00000000`0946e100 00000642`80bb5675 : 00000000`8084d918 00000642`8080ff12 00000000`80851dd8 00000000`80851dd8 : 0x642`80bb56d4 00000000`0946e130 00000642`80bb5532 : 00000000`808514e0 00000642`80667839 00000000`8084d918 00000000`00000000 : 0x642`80bb5675 00000000`0946e170 00000642`80b220d7 : 00000000`8084d918 00000000`0946e1e8 00000000`c03a6901 00000000`0946e201 : 0x642`80bb5532 00000000`0946e1c0 00000642`80b18c5a : 00000000`8084d918 00000000`8084d901 00000000`c04eb001 00000642`8066c08f : 0x642`80b220d7 00000000`0946e280 00000642`80b18b1e : 00000000`8084d918 00000000`80846f78 00000000`8084d901 00000000`0946e3e0 : 0x642`80b18c5a 00000000`0946e2e0 00000642`80b141c7 : 00000000`8084d918 00000642`80a5c431 00000000`80846f78 00000001`00000001 : 0x642`80b18b1e 00000000`0946e340 00000642`81c6fea4 : 00000000`80846f78 00000000`80846f78 00000000`8084d918 00000000`0946e3e0 : 0x642`80b141c7 00000000`0946e390 00000642`80a5c184 : 00000000`8084d918 00000000`80846f78 00000000`c00030d0 00000642`80660546 : 0x642`81c6fea4 00000000`0946e3c0 00000642`80a229d1 : 00000000`80244a80 c2000001`60008e8c 00000000`80242908 00000000`8084b668 : 0x642`80a5c184 00000000`0946e450 00000642`80a20949 : 00000000`80242908 00000000`80244a80 00000000`0946e4f8 00000642`8046a592 : 0x642`80a229d1 00000000`0946e4d0 00000642`80a2056c : 00000000`802447c8 00000000`00000000 00000000`80032528 00000642`80a204ad : 0x642`80a20949 00000000`0946e570 00000642`8066a599 : 00000000`7fff3c60 00000000`0946e650 48d3681c`1b957ce1 00000000`00000000 : 0x642`80a2056c 00000000`0946e5c0 00000642`80667178 : 00000000`c0002ab8 00000000`80846640 00000000`0946e948 00000000`00000002 : 0x642`8066a599 00000000`0946e630 00000642`7f5fcda2 : 00000000`8003e260 00000000`02fe0950 00000000`00000002 ffffffff`fffffffe : 0x642`80667178 00000000`0946e740 00000642`7f5069f3 : 00000000`0946e820 00000000`0946e8f0 ffffffff`fffffffe 00000000`00000000 : mscorwks!CallDescrWorker+0x82 00000000`0946e7a0 00000642`7f521e10 : 00000000`0946e930 00000000`0946eef0 00000000`00000003 00000000`00000003 : mscorwks!CallDescrWorkerWithHandler+0xd3 00000000`0946e840 00000642`7f52217b : 00000000`03314460 00000000`00081800 00000000`00000000 00000642`00000004 : mscorwks!ForwardCallToManagedMethod+0x160 00000000`0946e8e0 00000642`7f542918 : 00000000`0493cc00 00000000`0b326010 ffffffff`fffffffe 00000000`0b326260 : mscorwks!COMToCLRWorkerBody+0x35b 00000000`0946eb40 00000642`7f496506 : 00000000`00000000 00000000`0946ecb8 00000000`0946ef30 00000000`00000000 : mscorwks!COMToCLRWorkerDebuggerWrapper+0x50 00000000`0946ebb0 00000642`7f5fcf1e : 00000000`0b326010 00000000`0946ef30 00000000`02fd4800 00000000`00000000 : mscorwks!COMToCLRWorker+0x366 00000000`0946eea0 00000642`fff582b3 : 00000000`04dbff20 00000000`02fe0950 00000000`00000002 00000000`0946ef90 : mscorwks!GenericComCallStub+0x5e 00000000`0946ef50 00000642`fff58693 : ffffffff`fffffffe 00000000`02fe0950 00000000`0a1ab230 00000000`00000001 : webengine!HttpCompletion::ProcessRequestInManagedCode+0x2a3 00000000`0946f400 00000642`fff9ad04 : 00000642`7fc08ca8 00000642`7fc08ca8 00000642`fff9ace0 00000000`00000001 : webengine!HttpCompletion::ProcessCompletion+0x63 00000000`0946f440 00000642`7f48feb7 : ffffffff`fffffffe 00000000`00000001 00000000`00000000 00000000`00000001 : webengine!CorThreadPoolWorkitemCallback+0x24 00000000`0946f470 00000642`7f4a7bea : 00000000`00000000 00000000`00000000 00000000`00000002 00000000`0b326010 : mscorwks!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x157 00000000`0946f510 00000642`7f421304 : 00000000`00000000 00000000`00000000 00000000`0946ff50 00000000`00000000 : mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba 00000000`0946f5b0 00000000`77d6b8ca : 00000000`77d6b890 00000000`00000000 00000000`00000000 00000000`0946ffa8 : mscorwks!Thread::intermediateThreadProc+0x78 00000000`0946ff80 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadStart+0x3a </pre> <br /> 상황을 보아하니, 아마도 System.TypeInitializationException 예외가 잡히는 시점에는 이미 오류 문맥을 벗어난 것이 아닌가... 하는 생각이 들었습니다. 어쨌든 System.TypeInitializationException 예외 이전에 System.AccessViolationException 예외가 발생한다는 사실을 알았으므로 procdump.exe를 이용해 다시 한번 System.AccessViolationException을 조건으로 덤프를 떴습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > procdump -ma -e 1 -f AccessVio* 3628 </pre> <br /> sos 확장도 다시 로드하고 System.AccessViolationException 예외가 발생한 스레드로 문맥 전환을 한 후, clrstack 명령어를 확인했지만 여전히 관리 코드내에서의 직접적인 원인은 나오지 않았습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>!clrstack</span> OS Thread Id: 0xcf0 (48) *** WARNING: Unable to verify checksum for TestUnmanaged64.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for TestUnmanaged64.dll - Child-SP RetAddr Call Site 000000000dcfdd70 0000064280b2e5b9 TestLib.TempWebPage.Page_Load(System.Object, System.EventArgs) 000000000dcfddd0 0000064280b2e574 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs) 000000000dcfde00 0000064280b2e515 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs) 000000000dcfde30 0000064280b2e3d2 System.Web.UI.Control.OnLoad(System.EventArgs) 000000000dcfde70 0000064280b26337 System.Web.UI.Control.LoadRecursive() 000000000dcfdec0 0000064280b1855a System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean) 000000000dcfdf80 0000064280b1841e System.Web.UI.Page.ProcessRequest(Boolean, Boolean) 000000000dcfdfe0 0000064280b13b47 System.Web.UI.Page.ProcessRequest() 000000000dcfe040 0000064281896f94 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext) 000000000dcfe090 0000064280a5bbb4 ASP.j5_TempWebPage_aspx.ProcessRequest(System.Web.HttpContext) 000000000dcfe0c0 0000064280a22371 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 000000000dcfe150 0000064280a202e9 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef) 000000000dcfe1d0 000006428080fc1c System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception) 000000000dcfe270 000006428066a599 System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object) 000000000dcfe2c0 0000064280667178 System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest) 000000000dcfe330 000006427f5fcda2 System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32) </pre> <br /> 그런데, native 콜 스택에는 제가 작성한 함수의 콜 스택이 나왔습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>kv</span> Child-SP RetAddr : Args to Child : Call Site 00000000`0dcf2e78 00000000`77d706af : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwWaitForSingleObject+0xa ...[생략]... 00000000`0dcf3220 00000642`7f96701a : 00000000`067a11d0 00000642`7f53716c 00000000`00000001 00000000`00000000 : mscorwks!Debugger::SendException+0x518 00000000`0dcf37f0 00000642`7f8341ef : 00000000`0383de98 00000000`067a11d0 00000000`05022198 00000642`00000000 : mscorwks!Debugger::FirstChanceManagedException+0x2a 00000000`0dcf3850 00000642`7f4fe870 : 00000000`0383de60 00000000`0dcf4770 00000000`0dcfdd70 00000000`00000000 : mscorwks! ?? ::FNODOBFM::`string'+0xa68cf 00000000`0dcf3aa0 00000642`7f4ffcff : 00000642`818976b2 00000642`81c8613c 00000000`0dcf55b0 00000000`0dcf4a78 : mscorwks!ExceptionTracker::ProcessOSExceptionNotification+0x430 00000000`0dcf4960 00000000`77ee3d4d : 00000642`00000000 00000000`0dcfdd70 00000000`0dcf55b0 00000000`00000000 : mscorwks!ProcessCLRException+0x19b 00000000`0dcf4a00 00000000`77ee5857 : 00000000`00000001 00000000`00000000 00000000`0dcf55b0 00000000`0dcfdca0 : ntdll!RtlpExecuteHandlerForException+0xd 00000000`0dcf4a30 00000000`77ef2a3d : 00000000`00000000 00000000`0dcf50e0 00000000`000000c0 00000000`0dcf7960 : ntdll!RtlDispatchException+0x1b4 00000000`0dcf50e0 00000001`80013f70 : 00000000`000000bf 00000000`0a7c4f40 00000001`800809c0 00000000`00000001 : ntdll!KiUserExceptionDispatch+0x2d (TrapFrame @ 00000000`0dcf54e8) <span style='color: blue; font-weight: bold'>00000000`0dcf5680 00000001`8001b21c : 00000000`0000001c 00000000`0000001c 00000001`80081e20 00000000`000000c0 : TestUnmanaged64+0x13f70 00000000`0dcf5740 00000001`8001379d : 00000000`0dcf63e0 00000000`00000000 00000001`800813b8 00000000`0dcf64c0 : TestUnmanaged64+0x1b21c 00000000`0dcf61b0 00000001`80026848 : 00000000`00000200 00000000`00000000 00720065`00660069 0057002e`00300034 : TestUnmanaged64+0x1379d 00000000`0dcf7910 00000001`8002427a : 00000000`09e568a0 00000000`00000000 00000000`00000000 00000642`803f6008 : TestUnmanaged64+0x26848 00000000`0dcf8040 00000001`800228ef : 00000000`00158330 00000000`0015e208 00000000`0015e208 00000000`06612ed0 : TestUnmanaged64+0x2427a 00000000`0dcfd7d0 00000642`ff8d6443 : 00000000`0aa3b398 00000642`7fc136c0 00000000`0dcfd8b0 00000642`7f4bb54e : TestUnmanaged64+0x228ef</span> ...[생략]... </pre> <br /> 단지 PDB가 올라오지 않아 "TestUnmanaged64+0x1b21c" 와 같은 식으로만 콜 스택이 나오는 군요. 실제로 lm 으로 확인해 보니 해당 DLL의 pdb가 deferred로 표시되어 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>lm</span> start end module name 00000000`00400000 00000000`00406000 w3wp (deferred) ...[생략]... 00000000`13760000 00000000`1395b000 sybdrvado20 (deferred) 00000000`13970000 00000000`139a3000 WebTestHelper64 (deferred) 00000000`13a60000 00000000`13a6a000 App_Web_h4pa_7ul (deferred) <span style='color: blue; font-weight: bold'>00000001`80000000 00000001`800c3000 TestUnmanaged64 (deferred)</span> ...[생략]... 000007ff`7fee0000 000007ff`7ffe9000 advapi32 (deferred) Unloaded modules: 000007ff`7b0f0000 000007ff`7b20e000 RichEd20.dll 000007ff`79230000 000007ff`7924e000 digest.dll 000007ff`7dd50000 000007ff`7dd95000 schannel.dll 00000642`ff4a0000 00000642`ff4aa000 culture.dll </pre> <br /> 재미있는 것은, TestUnmanaged64.dll이 위치한 동일한 폴더에 TestUnmanaged64.pdb 파일이 있었는데도 ".realod -f" 명령어로는 PDB가 올라오지 않았다는 점입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>.reload -f</span> ...................................*** ERROR: Module load completed but symbols could not be loaded for iisres.dll Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long. Run !sym noisy before .reload to track down problems loading symbols. .........................*** WARNING: Unable to verify checksum for TestUnmanaged64.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for TestUnmanaged64.dll - </pre> <br /> 어쩔 수 없군요. 이럴 때는 noisy 모드를 켜고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>!sym noisy</span> noisy mode - symbol prompts on </pre> <br /> 다시 한번 .reload -f 명령어를 내리면 windbg가 찾으려는 PDB 경로가 함께 출력되므로 이를 검사하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ...[생략]... <span style='color: blue; font-weight: bold'>SYMSRV: d:\symbols\TestUnmanaged64.pdb\91F30530ADD344D3895F7478DC17499C1\TestUnmanaged64.pdb not found SYMSRV: http://msdl.microsoft.com/download/symbols/TestUnmanaged64.pdb/91F30530ADD344D3895F7478DC17499C1/TestUnmanaged64.pdb not found DBGHELP: D:\TestWebSite\TestUnmanaged\bin\Release\TestUnmanaged64.pdb - file not found</span> *** WARNING: Unable to verify checksum for TestUnmanaged64.dll *** ERROR: Symbol file could not be found. Defaulted to export symbols for TestUnmanaged64.dll - DBGHELP: TestUnmanaged64 - export symbols ...[생략]... </pre> <br /> 저 3개의 경로 중 하나에만 넣어주면 되는데요. 제 경우에는 그냥 "D:\TestWebSite\TestUnmanaged\bin\Release\TestUnmanaged64.pdb"로 위치시키고 다시 .reload -f를 내려 로드를 했습니다. 그럼, 이번에는 다음과 같이 "private symbols & lines" 메시지를 통해 PDB를 정상적으로 로드했음을 확인할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ...[생략]... SYMSRV: d:\symbols\TestUnmanaged64.pdb\91F30530ADD344D3895F7478DC17499C1\TestUnmanaged64.pdb not found SYMSRV: http://msdl.microsoft.com/download/symbols/TestUnmanaged64.pdb/91F30530ADD344D3895F7478DC17499C1/TestUnmanaged64.pdb not found *** WARNING: Unable to verify checksum for TestUnmanaged64.dll <span style='color: blue; font-weight: bold'>DBGHELP: TestUnmanaged64 - private symbols & lines</span> ...[생략]... </pre> <br /> 이 상태에서 kv 콜 스택을 확인하면... 와~~~ ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:048> <span style='color: blue; font-weight: bold'>kv</span> DBGHELP: kernel32 - public symbols d:\symbols\kernel32.pdb\19C002F7F64C463C91C1E8CEDF84B0252\kernel32.pdb Child-SP RetAddr : Args to Child : Call Site 00000000`0dcf2e78 00000000`77d706af : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwWaitForSingleObject+0xa 00000000`0dcf2e80 00000642`7f494b46 : 00000000`00000eb8 00000000`00000000 00000000`00000000 00000000`ffffffff : kernel32!WaitForSingleObjectEx+0x130 ...[생략].... <span style='color: blue; font-weight: bold'>00000000`0dcf5680 00000001`8001b21c : 00000000`0000001c 00000000`0000001c 00000001`80081e20 00000000`000000c0 : TestUnmanaged64!MyNativeType::TestMethod+0x60 [d:\TestWebSite\TestUnmanaged64\MyNativeType.cpp @ 2341] </span> ...[생략].... 00000000`0dcfff80 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadStart+0x3a </pre> <br /> 소스 코드 라인 번호까지 나왔으니... 게임 끝입니다. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이 문제에서 재미있었던 점이 하나 있는데요. 해당 문제는 Unmanaged 환경의 C++ 코드에서 발생했기 때문에 사실 C/C++의 AccessViolation 예외가 발생하는 것이 정상입니다. 대충 이런 식이어야 하는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unhandled exception at 0x0fc716b7 (TestUnmanaged64.dll) in w3wp.exe: 0xC0000005: Access violation. </pre> <br /> 그런데, 쌩뚱맞게도 그것이 Managed 수준으로 넘어와 System.AccessViolationException 예외가 던져졌기 때문에 문제 파악에 혼란이 온 것입니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6177
(왼쪽의 숫자를 입력해야 합니다.)