Microsoft MVP성태의 닷넷 이야기
오류 유형: 102. System.MissingMethodException [링크 복사], [링크+제목 복사],
조회: 33281
글쓴 사람
정성태 (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

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13641정성태6/11/20248673Linux: 71. Ubuntu 20.04를 22.04로 업데이트
13640정성태6/10/20248842Phone: 21. C# MAUI - Android 환경에서의 파일 다운로드(DownloadManager)
13639정성태6/8/20248448오류 유형: 906. C# MAUI - Android Emulator에서 "Waiting For Debugger"로 무한 대기
13638정성태6/8/20248531오류 유형: 905. C# MAUI - 추가한 layout XML 파일이 Resource.Layout 멤버로 나오지 않는 문제
13637정성태6/6/20248458Phone: 20. C# MAUI - 유튜브 동영상을 MediaElement로 재생하는 방법
13636정성태5/30/20248097닷넷: 2264. C# - 형식 인자로 인터페이스를 갖는 제네릭 타입으로의 형변환파일 다운로드1
13635정성태5/29/20248962Phone: 19. C# MAUI - 안드로이드 "Share" 대상으로 등록하는 방법
13634정성태5/24/20249433Phone: 18. C# MAUI - 안드로이드 플랫폼에서의 Activity 제어 [1]
13633정성태5/22/20248961스크립트: 64. 파이썬 - ASGI를 만족하는 최소한의 구현 코드
13632정성태5/20/20248575Phone: 17. C# MAUI - Android 내에 Web 서비스 호스팅
13631정성태5/19/20249331Phone: 16. C# MAUI - /Download 등의 공용 디렉터리에 접근하는 방법 [1]
13630정성태5/19/20248880닷넷: 2263. C# - Thread가 Task보다 더 빠르다는 어떤 예제(?)
13629정성태5/18/20249170개발 환경 구성: 710. Android - adb.exe를 이용한 파일 전송
13628정성태5/17/20248553개발 환경 구성: 709. Windows - WHPX(Windows Hypervisor Platform)를 이용한 Android Emulator 가속
13627정성태5/17/20248619오류 유형: 904. 파이썬 - UnicodeEncodeError: 'ascii' codec can't encode character '...' in position ...: ordinal not in range(128)
13626정성태5/15/20248886Phone: 15. C# MAUI - MediaElement Source 경로 지정 방법파일 다운로드1
13625정성태5/14/20248936닷넷: 2262. C# - Exception Filter 조건(when)을 갖는 catch 절의 IL 구조
13624정성태5/12/20248731Phone: 14. C# - MAUI에서 MediaElement 사용파일 다운로드1
13623정성태5/11/20248430닷넷: 2261. C# - 구글 OAuth의 JWT (JSON Web Tokens) 해석파일 다운로드1
13622정성태5/10/20249224닷넷: 2260. C# - Google 로그인 연동 (ASP.NET 예제)파일 다운로드1
13621정성태5/10/20248644오류 유형: 903. IISExpress - Failed to register URL "..." for site "..." application "/". Error description: Cannot create a file when that file already exists. (0x800700b7)
13620정성태5/9/20248561VS.NET IDE: 190. Visual Studio가 node.exe를 경유해 Edge.exe를 띄우는 경우
13619정성태5/7/20248874닷넷: 2259. C# - decimal 저장소의 비트 구조파일 다운로드1
13618정성태5/6/20248665닷넷: 2258. C# - double (배정도 실수) 저장소의 비트 구조파일 다운로드1
13617정성태5/5/20249477닷넷: 2257. C# - float (단정도 실수) 저장소의 비트 구조파일 다운로드1
13616정성태5/3/20248642닷넷: 2256. ASP.NET Core 웹 사이트의 HTTP/HTTPS + Dual mode Socket (IPv4/IPv6) 지원 방법파일 다운로드1
1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...