성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>System.MissingMethodException</div> <br /> 특정 컴퓨터에서 제품 설치 후 w3wp.exe가 죽는다는 보고가 왔습니다. 설치된 환경을 문의하니 정확히 ".NET Framework 2.0"만 설치되고 더 이상 윈도우 업데이트를 받지 않고 있는 사이트임을 알게 되었습니다.<br /> <br /> 그래서, 동일하게 Virtual PC를 구성하고. (도대체, Virtual PC가 없던 시절에는 다들 어떻게 제품 개발을 했을까나... ^^;)<br /> <br /> 재현을 해보았더니, 여지없이 이벤트 로그에 고객 사이트에서 발생한 것과 동일한 오류가 떴습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Event Type: Error Event Source: .NET Runtime 2.0 Error Reporting Event Category: None Event ID: 5000 Date: 8/17/2010 Time: 3:54:48 PM User: N/A Computer: WIN2K3CLR2 Description: <b style='COLOR: blue'>EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.3959, P3 45d6968e, P4 mscorlib, P5 2.0.0.0, P6 4333ab80, P7 122f, P8 14, P9 system.missingmethodexception, P10 NIL.</b> For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. Data: 0000: 63 00 6c 00 72 00 32 00 c.l.r.2. ... [생략] ... 00e0: 20 00 4e 00 49 00 4c 00 .N.I.L. 00e8: 0d 00 0a 00 .... </pre> <br /> 위의 "Description"에 있는 정보의 해독은 예전 글에서 소개해 드렸지요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Watson Bucket 정보를 이용한 CLR 응용 프로그램 예외 분석 ; <a target='_tab' href='/2/0/595'>http://www.sysnet.pe.kr/2/0/595</a> </pre> <br /> 우선, MethodDef == 122f임을 알고 있으니 ILDASM.exe에서 다음과 같이 찾아낼 수 있습니다. (반드시, CLR 2.0만 설치된 mscorlib.dll을 검사해야 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > TypeDef #335 (02000150) ------------------------------------------------------- TypDefName: <b style='COLOR: blue'>System.Threading.ThreadHelper</b> (02000150) Flags : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] (00100000) Extends : 02000002 [TypeDef] System.Object ...[생략]... Method #3 (0600122f) ------------------------------------------------------- MethodName: <b style='COLOR: blue'>ThreadStart_Context</b> (0600<b style='COLOR: blue'>122F</b>) Flags : [Assem] [Static] [HideBySig] [ReuseSlot] (00000093) RVA : 0x00032628 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void 1 Arguments Argument #1: Object 1 Parameters (1) ParamToken : (0800192e) Name : state flags: [none] (00000000) </pre> <br /> 오호... ThreadStart_Context 메서드에서 무슨 일이 있었던 걸까요? 문제가 발생한 IL Code 옵셋 == 0x14를 찾아들어가니 다음과 같은 코드가 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > .method assembly hidebysig static void ThreadStart_Context(object state) cil managed { // Code size 60 (0x3c) .maxstack 2 .locals init (class System.Threading.ThreadHelper V_0) IL_0000: ldarg.0 IL_0001: castclass System.Threading.ThreadHelper IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldfld class System.Delegate System.Threading.ThreadHelper::_start IL_000d: isinst System.Threading.ThreadStart IL_0012: brfalse.s IL_0025 <b style='COLOR: blue'>IL_0014: ldloc.0</b> IL_0015: ldfld class System.Delegate System.Threading.ThreadHelper::_start IL_001a: castclass System.Threading.ThreadStart IL_001f: callvirt instance void System.Threading.ThreadStart::Invoke() IL_0024: ret IL_0025: ldloc.0 IL_0026: ldfld class System.Delegate System.Threading.ThreadHelper::_start IL_002b: castclass System.Threading.ParameterizedThreadStart IL_0030: ldloc.0 IL_0031: ldfld object System.Threading.ThreadHelper::_startArg IL_0036: callvirt instance void System.Threading.ParameterizedThreadStart::Invoke(object) IL_003b: ret } // end of method ThreadHelper::ThreadStart_Context </pre> <br /> 이건 좀 의외군요. ldloc 코드에서 System.MissingMethodException 같은 예외가 발생한다는 것이 잘 납득이 되질 않습니다. 일단 "Watson Bucket" 분석은 이 정도로 끝내고.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 이런 식으로 문제 재현이 되는 PC가 마음대로 접근할 수 있는 환경이라면, 당연히 Visual Studio의 강력한 디버깅 기능인 "원격 디버깅"을 사용해서 대부분의 문제를 해결할 수 있습니다.<br /> <br /> 문제는, 해당 ASP.NET 웹 애플리케이션이 실행되자마자 죽어버린다는 것입니다. "원격 디버깅"을 걸려면 "프로세스 목록"을 열람해야 하는데 그 작업을 들어갈 수가 없는 것입니다.<br /> <br /> 이런 경우에, ^^ 제가 주로 써 먹는 방법이 있는데요. 바로 ^^ ASP.NET이 올라오긴 전 상태로 w3wp.exe를 띄워놓기만 한 후 원격 디버거를 붙이는 것입니다. 다음과 같이 따라해주시면 어렵지 않게 할 수 있습니다.<br /> <br /> <ol> <li>만약 w3wp.exe가 실행중이라면 종료시키고,</li> <li>http://.../test.test와 같이 있지도 않은 페이지를 방문 시도.</li> <li>그럼, w3wp.exe가 실행되는데 이 상태에서는 .NET이 올라와 있지 않게 됩니다.</li> <li>이 시점에서 w3wp.exe 프로세스에 대해 Debugger를 attach 시켜 놓고. (BP 설정도 하고.)</li> <li>정식으로 aspx 페이지를 방문하면, 그제서야 ASP.NET 관련 DLL들이 올라오면서 예외를 잡을 수 있습니다.</li> </ol> <br /> 위와 같이 해서, 원격 디버깅 상태로 조사해 본 결과, 범인은 System.Threading.WaitHandle의 "public virtual bool WaitOne(int millisecondsTimeout);" 메서드였습니다.<br /> <br /> <img alt='missing_method_ex_clr2_1.png' src='/SysWebRes/bbs/missing_method_ex_clr2_1.png' /><br /> <br /> 도움말에서 찾아보니 "WaitOne(int millisecondsTimeout);" 메서드가 추가된 것은 2.0 SP2라고 되어 있는데 즉, 해당 사이트에서는 2.0 SP2 이후의 업데이트를 포함하고 있지 않아서 발생한 문제였습니다. (제품 개발을 하고 있는 제 PC를 포함해서 테스트 서버 4대 모두 윈도우 업데이트를 받고 있기 때문에 이런 문제가 미리 발견되지 못한 것이었습니다.)<br /> <br /> 휴~~~~ 솔루션 개발이란! ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 여기서 한 가지 궁금한 사항이 있는데요. 아니... 그렇다면 Watson 버킷의 오류 보고 내용이 틀렸다는 것일까요?<br /> 결론적으로 틀렸다고는 말할 수 없지만, 어쨌든 직관적이지 않은 것만은 사실입니다.<br /> <br /> 해당 예외가 발생했을 때의 원격 디버깅 상에서의 콜스택을 보니 다음과 같았습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > at MyProduct.MyClass.MyFunc.Run() at <b style='COLOR: blue'>System.Threading.ThreadHelper.ThreadStart_Context</b>(Object state) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() </pre> <br /> 그러니까, Threadstart_Context를 실행하면서 WaitOne에 대한 함수를 찾을 수 없으니 그와 같은 예외가 발생한 것입니다.<br /> <br /> 문제가 되었던 코드로 돌아가 볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > .method assembly hidebysig static void ThreadStart_Context(object state) cil managed { // Code size 60 (0x3c) .maxstack 2 .locals init (class System.Threading.ThreadHelper V_0) IL_0000: ldarg.0 IL_0001: castclass System.Threading.ThreadHelper IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldfld class System.Delegate System.Threading.ThreadHelper::_start IL_000d: isinst System.Threading.ThreadStart IL_0012: brfalse.s IL_0025 <b style='COLOR: blue'>IL_0014: ldloc.0</b> ...[생략]... } </pre> <br /> 위에서 보면, "IL_0014" 옵셋에서 로드되는 인스턴스가 바로 사용자의 델리게이트 함수입니다. 즉, 사용자가 정의한 MyClass.MyFunc.Run 메서드가 적재되는 그 순간에 JIT 컴파일 과정이 이뤄지고 Run 메서드 내에 포함되어 있던 WaitOne 메서드를 찾을 수 없어 System.MissingMethodException 예외가 발생했던 것입니다.<br /> <br /> 어쨌든... 결국 System.MissingMethodException 같은 경우에는, <a target='_tab' href='/2/0/595'>지난번 설명해 드렸던 것</a>과는 달리 이벤트 로그의 정보만으로는 직접적인 문제 해결을 할 수 없다는 한계가 있다는 것을 알아둘 필요가 있겠습니다. (덤프를 떠서 windbg로 분석하면 나오겠군요.)<br /> <br /> 그나저나, 다중 CLR 버전을 지원하는 제품 개발에서는 System.MissingMethodException 예외를 아주 조심해야 할 것 같습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Method not found: 'Void System.Reflection.Emit.DynamicMethod..ctor(System.String, System.Type, System.Type[])'. ; <a target='_tab' href='/2/0/809'>http://www.sysnet.pe.kr/2/0/809</a> </pre> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
8957
(왼쪽의 숫자를 입력해야 합니다.)