Microsoft MVP성태의 닷넷 이야기
오류 유형: 102. System.MissingMethodException [링크 복사], [링크+제목 복사],
조회: 33354
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 4개 있습니다.)
System.MissingMethodException

특정 컴퓨터에서 제품 설치 후 w3wp.exe가 죽는다는 보고가 왔습니다. 설치된 환경을 문의하니 정확히 ".NET Framework 2.0"만 설치되고 더 이상 윈도우 업데이트를 받지 않고 있는 사이트임을 알게 되었습니다.

그래서, 동일하게 Virtual PC를 구성하고. (도대체, Virtual PC가 없던 시절에는 다들 어떻게 제품 개발을 했을까나... ^^;)

재현을 해보았더니, 여지없이 이벤트 로그에 고객 사이트에서 발생한 것과 동일한 오류가 떴습니다.

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:
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.

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               ....    

위의 "Description"에 있는 정보의 해독은 예전 글에서 소개해 드렸지요.

Watson Bucket 정보를 이용한 CLR 응용 프로그램 예외 분석
; https://www.sysnet.pe.kr/2/0/595

우선, MethodDef == 122f임을 알고 있으니 ILDASM.exe에서 다음과 같이 찾아낼 수 있습니다. (반드시, CLR 2.0만 설치된 mscorlib.dll을 검사해야 합니다.)

TypeDef #335 (02000150)
-------------------------------------------------------
    TypDefName: System.Threading.ThreadHelper  (02000150)
    Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
    Extends   : 02000002 [TypeDef] System.Object

...[생략]...

    Method #3 (0600122f) 
    -------------------------------------------------------
        MethodName: ThreadStart_Context (0600122F)
        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)

오호... ThreadStart_Context 메서드에서 무슨 일이 있었던 걸까요? 문제가 발생한 IL Code 옵셋 == 0x14를 찾아들어가니 다음과 같은 코드가 있습니다.

.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
  IL_0014:  ldloc.0
  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

이건 좀 의외군요. ldloc 코드에서 System.MissingMethodException 같은 예외가 발생한다는 것이 잘 납득이 되질 않습니다. 일단 "Watson Bucket" 분석은 이 정도로 끝내고.




이런 식으로 문제 재현이 되는 PC가 마음대로 접근할 수 있는 환경이라면, 당연히 Visual Studio의 강력한 디버깅 기능인 "원격 디버깅"을 사용해서 대부분의 문제를 해결할 수 있습니다.

문제는, 해당 ASP.NET 웹 애플리케이션이 실행되자마자 죽어버린다는 것입니다. "원격 디버깅"을 걸려면 "프로세스 목록"을 열람해야 하는데 그 작업을 들어갈 수가 없는 것입니다.

이런 경우에, ^^ 제가 주로 써 먹는 방법이 있는데요. 바로 ^^ ASP.NET이 올라오긴 전 상태로 w3wp.exe를 띄워놓기만 한 후 원격 디버거를 붙이는 것입니다. 다음과 같이 따라해주시면 어렵지 않게 할 수 있습니다.

  1. 만약 w3wp.exe가 실행중이라면 종료시키고,
  2. http://.../test.test와 같이 있지도 않은 페이지를 방문 시도.
  3. 그럼, w3wp.exe가 실행되는데 이 상태에서는 .NET이 올라와 있지 않게 됩니다.
  4. 이 시점에서 w3wp.exe 프로세스에 대해 Debugger를 attach 시켜 놓고. (BP 설정도 하고.)
  5. 정식으로 aspx 페이지를 방문하면, 그제서야 ASP.NET 관련 DLL들이 올라오면서 예외를 잡을 수 있습니다.

위와 같이 해서, 원격 디버깅 상태로 조사해 본 결과, 범인은 System.Threading.WaitHandle의 "public virtual bool WaitOne(int millisecondsTimeout);" 메서드였습니다.

missing_method_ex_clr2_1.png

도움말에서 찾아보니 "WaitOne(int millisecondsTimeout);" 메서드가 추가된 것은 2.0 SP2라고 되어 있는데 즉, 해당 사이트에서는 2.0 SP2 이후의 업데이트를 포함하고 있지 않아서 발생한 문제였습니다. (제품 개발을 하고 있는 제 PC를 포함해서 테스트 서버 4대 모두 윈도우 업데이트를 받고 있기 때문에 이런 문제가 미리 발견되지 못한 것이었습니다.)

휴~~~~ 솔루션 개발이란! ^^




여기서 한 가지 궁금한 사항이 있는데요. 아니... 그렇다면 Watson 버킷의 오류 보고 내용이 틀렸다는 것일까요?
결론적으로 틀렸다고는 말할 수 없지만, 어쨌든 직관적이지 않은 것만은 사실입니다.

해당 예외가 발생했을 때의 원격 디버깅 상에서의 콜스택을 보니 다음과 같았습니다.

at MyProduct.MyClass.MyFunc.Run()
at System.Threading.ThreadHelper.ThreadStart_Context(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()

그러니까, Threadstart_Context를 실행하면서 WaitOne에 대한 함수를 찾을 수 없으니 그와 같은 예외가 발생한 것입니다.

문제가 되었던 코드로 돌아가 볼까요?

.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
  IL_0014:  ldloc.0
  ...[생략]...
}

위에서 보면, "IL_0014" 옵셋에서 로드되는 인스턴스가 바로 사용자의 델리게이트 함수입니다. 즉, 사용자가 정의한 MyClass.MyFunc.Run 메서드가 적재되는 그 순간에 JIT 컴파일 과정이 이뤄지고 Run 메서드 내에 포함되어 있던 WaitOne 메서드를 찾을 수 없어 System.MissingMethodException 예외가 발생했던 것입니다.

어쨌든... 결국 System.MissingMethodException 같은 경우에는, 지난번 설명해 드렸던 것과는 달리 이벤트 로그의 정보만으로는 직접적인 문제 해결을 할 수 없다는 한계가 있다는 것을 알아둘 필요가 있겠습니다. (덤프를 떠서 windbg로 분석하면 나오겠군요.)

그나저나, 다중 CLR 버전을 지원하는 제품 개발에서는 System.MissingMethodException 예외를 아주 조심해야 할 것 같습니다. ^^

Method not found: 'Void System.Reflection.Emit.DynamicMethod..ctor(System.String, System.Type, System.Type[])'.
; https://www.sysnet.pe.kr/2/0/809



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/27/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 91  92  93  94  95  96  97  98  99  100  [101]  102  103  104  105  ...
NoWriterDateCnt.TitleFile(s)
11407정성태12/18/201724229.NET Framework: 712. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 + Direct2D 출력 + OpenCV [1]파일 다운로드1
11406정성태12/17/201746634.NET Framework: 711. C# - OpenCvSharp의 Mat 데이터 조작 방법 [5]파일 다운로드1
11405정성태12/17/201742662.NET Framework: 710. C# - OpenCvSharp을 이용한 Webcam 영상 처리 + Direct2D [1]파일 다운로드1
11404정성태12/16/201729916.NET Framework: 709. C# - OpenCvSharp을 이용한 동영상(avi, mp4, ...) 처리 + Direct2D [7]파일 다운로드1
11403정성태12/16/201732528.NET Framework: 708. C# - OpenCvSharp을 이용한 동영상(avi, mp4, ...) 처리 [3]파일 다운로드1
11402정성태12/15/201737176.NET Framework: 707. OpenCV 응용 프로그램을 C#으로 구현 - OpenCvSharp [2]파일 다운로드1
11401정성태12/15/201726106.NET Framework: 706. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 + Direct2D 출력 [2]파일 다운로드1
11400정성태12/14/201728973.NET Framework: 705. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 [9]파일 다운로드1
11399정성태12/13/201717605.NET Framework: 704. Win32 API의 UnionRect를 닷넷 BCL의 Rectangle.Union으로 바꿀 때 주의 사항
11398정성태12/13/201717808오류 유형: 442. ASP.NET Core Web Application (on .NET Framework) 프로젝트에서 외부 라이브러리 동적 로드 시 런타임 버전 문제파일 다운로드1
11397정성태12/12/201720403.NET Framework: 703. 양자 컴퓨팅을 위한 마이크로소프트의 Q# 언어
11396정성태12/8/201742787개발 환경 구성: 343. Visual Studio - 리눅스 용 프로젝트의 인텔리센스를 위한 헤더 파일 처리 방법 [3]
11395정성태12/8/201718624오류 유형: 441. 이벤트 로그 - Time Provider NtpClient: No valid response has been received from domain controller
11394정성태12/8/201718257개발 환경 구성: 342. 비주얼 스튜디오에서 실행하던 ASP.NET Core (.NET Framework) 응용 프로그램을 명령행에서 실행하는 방법
11393정성태12/7/201722824Windows: 145. 윈도우 10 빌드 17046부터 WSL에서 백그라운드 작업 지원 [5]
11392정성태12/7/201718071개발 환경 구성: 341. openSUSE에 닷넷 코어 설치
11391정성태12/7/201720925개발 환경 구성: 340. WSL을 이용해 윈도우 PC 1대에서 openSUSE 응용 프로그램을 Visual Studio로 개발하는 방법 [1]
11390정성태12/7/201729581개발 환경 구성: 339. WSL을 이용해 윈도우 PC 1대에서 Linux 응용 프로그램을 Visual Studio로 개발하는 방법 [6]
11389정성태12/7/201718254오류 유형: 440. .NET Core 오류 - 0x80131620 Unable to load DLL 'libuv'
11388정성태12/6/201721889개발 환경 구성: 338. WSL 또는 Ubuntu에 닷넷 코어 설치 [3]
11387정성태12/6/201722250오류 유형: 439. 이벤트 로그 - Data Sharing Service 서비스의 %%3239247874 오류 메시지
11386정성태12/5/201717814오류 유형: 438. Hyper-V - '...' failed to add device 'Virtual CD/DVD Disk'
11385정성태12/5/201730926VC++: 121. DXGI를 이용한 윈도우 화면 캡처 소스 코드(Visual C++) [16]파일 다운로드1
11384정성태12/5/201720224오류 유형: 437. Visual C++ - Cannot open include file: 'SDKDDKVer.h'
11383정성태12/4/201723312디버깅 기술: 110. 비동기 코드 실행 중 예외로 인한 ASP.NET 프로세스 비정상 종료 현상 [1]
11382정성태12/4/201721890오류 유형: 436. System.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired 예외 발생 시 "[Pre-Login] initialization=48; handshake=1944;" 값의 의미
... 91  92  93  94  95  96  97  98  99  100  [101]  102  103  104  105  ...