Microsoft MVP성태의 닷넷 이야기
오류 유형: 102. System.MissingMethodException [링크 복사], [링크+제목 복사],
조회: 28129
글쓴 사람
정성태 (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)
13262정성태2/15/20235250디버깅 기술: 191. dnSpy를 이용한 (소스 코드가 없는) 닷넷 응용 프로그램 디버깅 방법 [1]
13261정성태2/15/20234544Windows: 224. Visual Studio - 영문 폰트가 Fullwidth Latin Character로 바뀌는 문제
13260정성태2/14/20234337오류 유형: 847. ilasm.exe 컴파일 오류 - error : syntax error at token '-' in ... -inf
13259정성태2/14/20234498.NET Framework: 2095. C# - .NET5부터 도입된 CollectionsMarshal
13258정성태2/13/20234348오류 유형: 846. .NET Framework 4.8 Developer Pack 설치 실패 - 0x81f40001
13257정성태2/13/20234410.NET Framework: 2094. C# - Job에 Process 포함하는 방법 [1]파일 다운로드1
13256정성태2/10/20235254개발 환경 구성: 665. WSL 2의 네트워크 통신 방법 - 두 번째 이야기
13255정성태2/10/20234593오류 유형: 845. gihub - windows2022 이미지에서 .NET Framework 4.5.2 미만의 프로젝트에 대한 빌드 오류
13254정성태2/10/20234517Windows: 223. (WMI 쿼리를 위한) PowerShell 문자열 escape 처리
13253정성태2/9/20235274Windows: 222. C# - 다른 윈도우 프로그램이 실행되었음을 인식하는 방법파일 다운로드1
13252정성태2/9/20234102오류 유형: 844. ssh로 명령어 수행 시 멈춤 현상
13251정성태2/8/20234540스크립트: 44. 파이썬의 3가지 스레드 ID
13250정성태2/8/20236405오류 유형: 843. System.InvalidOperationException - Unable to configure HTTPS endpoint
13249정성태2/7/20235219오류 유형: 842. 리눅스 - You must wait longer to change your password
13248정성태2/7/20234245오류 유형: 841. 리눅스 - [사용자 계정] is not in the sudoers file. This incident will be reported.
13247정성태2/7/20235128VS.NET IDE: 180. Visual Studio - 닷넷 소스 코드 디버깅 중 "Decompile source code"가 동작하는 않는 문제
13246정성태2/6/20234297개발 환경 구성: 664. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법 - 두 번째 이야기
13245정성태2/6/20234872.NET Framework: 2093. C# - PEM 파일을 이용한 RSA 개인키/공개키 설정 방법파일 다운로드1
13244정성태2/5/20234201VS.NET IDE: 179. Visual Studio - External Tools에 Shell 내장 명령어 등록
13243정성태2/5/20235041디버깅 기술: 190. windbg - Win32 API 호출 시점에 BP 거는 방법 [1]
13242정성태2/4/20234491디버깅 기술: 189. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.UnauthorizedAccessException
13241정성태2/3/20233956디버깅 기술: 188. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.IO.FileNotFoundException
13240정성태2/1/20234114디버깅 기술: 187. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.Web.HttpException
13239정성태2/1/20233787디버깅 기술: 186. C# - CacheDependency의 숨겨진 예외 - System.Web.HttpException
13238정성태1/31/20235888.NET Framework: 2092. IIS 웹 사이트를 TLS 1.2 또는 TLS 1.3 프로토콜로만 운영하는 방법
13237정성태1/30/20235573.NET Framework: 2091. C# - 웹 사이트가 어떤 버전의 TLS/SSL을 지원하는지 확인하는 방법
1  2  3  4  5  6  7  8  9  10  11  12  13  14  [15]  ...