Microsoft MVP성태의 닷넷 이야기
.NET Framework: 621. 닷넷 프로파일러의 오류 코드 - 0x80131363 [링크 복사], [링크+제목 복사],
조회: 21945
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

닷넷 프로파일러의 오류 코드 - 0x80131363

CORPROF_E_UNSUPPORTED_CALL_SEQUENCE (0x80131363) 오류에 대한 좀 더 상세한 정보가 있어서 소개합니다. ^^

Why we have CORPROF_E_UNSUPPORTED_CALL_SEQUENCE
; https://blogs.msdn.microsoft.com/davbr/2008/12/23/why-we-have-corprof_e_unsupported_call_sequence/

정리해 보면, 0x80131363 오류는 CLR 2.0부터 반환하도록 추가되었습니다. 이전에도 언급했지만,

닷넷 프로파일러의 오류 코드 정보
; https://www.sysnet.pe.kr/2/0/10880

0x80131363 오류는 ICorProfilerInfo 관련 메서드를 호출할 때 응용 프로그램이 불안정한 상태로 빠질 경우에 해당하면 반환됩니다. 이 오류는 주로 "hijacking profiler"에서 볼 수 있다고 합니다. (하지만, non-hijacking profiler에서도 발생할 수 있음.) hijacking profiler란? 프로파일러 관련 코드에 진입하기 위해 임의의 시점에 스레드의 레지스터 컨텍스트를 강제로 재설정하거나, 보통 그렇게 진입한 프로파일링 코드에서 ICorProfilerInfo를 이용해 CLR 내부로 재진입하는 종류의 프로파일러입니다.

왜 이것이 문제가 되냐면? 프로파일러가 스레드를 제어하기 시작했을 때 하필 CLR 내부의 자료 구조에 대한 lock을 소유할 경우도 있는데, 이 스레드에서 CLR 내부로 다시 재진입을 하게 되면 또 다른 lock을 가지는 것도 가능하게 되고 결국 deadlock이나 AV(Access Violation)에 쉽게 빠질 수 있다는 것입니다.

CLR 1.x까지는, 위와 같은 상황이 발생하면 '운에 따라' ICorProfilerInfo가 잘 호출될 수도 있고, 또는 deadlock/AV가 발생할 수도 있었지만 CLR 2.0부터는 아예 0x80131363을 반환해서 그런 상황을 미연에 방지하도록 합니다.

일반적으로 ICorProfilerCallback으로 호출되는 메서드 내에서 실행되는 코드로 이뤄진 non-hijacking profiler라면 ICorProfilerInfo 메서드를 호출하는 것은 문제가 없습니다. 예를 들어, ICorProfilerCallback::ClassLoadFinished 콜백 함수 내에서 클래스에 대한 정보를 요청하는 것은 괜찮습니다. 사실 이 시점에 클래스 정보가 완전하지 않아서 구할 수 없는 경우도 있는데 그럼 CORPROF_E_DATAINCOMPLETE를 반환할 뿐 deadlock이나 AV 오류가 발생할 염려는 없습니다. 이런 식으로 안전하게 ICorProfilerInfo를 호출하는 것을 "동기화(synchronous)"되었다고 합니다. 즉, ICorProfilerCallback 콜백 함수 내에서 호출되는 모든 유형은 synchronous에 해당하기 때문에 안전합니다.

반면, ICorProfilerCallback 콜백 함수가 아닌, 관리 스레드 상에서 ICorProfilerInfo가 제공하는 메서드를 호출하면 이를 "비동기화(asynchronous)"되었다고 합니다. 이러한 asynchronous 유형의 호출은 위험하며 CLR 2.0이후부터는 무조건 0x80131363 오류를 반환합니다.

asynchronous 상황에서 ICorProfilerInfo에서 제공하는 메서드들이 대체로 위험하긴 하지만, 다음의 메서드들은 허용된다고 합니다.

  • GetEventMask/SetEventMask
  • GetCurrentThreadID
  • GetThreadContext
  • GetThreadAppDomain
  • GetFunctionFromIP
  • GetFunctionInfo/GetFunctionInfo2
  • GetCodeInfo/GetCodeInfo2
  • GetModuleInfo
  • GetClassIDInfo/GetClassIDInfo2
  • IsArrayClass
  • SetFunctionIDMapper
  • DoStackSnapshot

그 외에 알아둘 점은?

  1. fast-path 방식의 Enter/Leave 콜백 내에서 ICorProfilerInfo 호출은 asynchronous로 간주합니다. (fast-path인지 slow-path인지에 대해서는 "https://blogs.msdn.microsoft.com/davbr/2007/03/22/enter-leave-tailcall-hooks-part-1-the-basics/?WT.mc_id=DT-MVP-4038148" 글을 참조) 반면 slow-path 방식의 Enter/Leave 콜백 내에서는 synchronous로 간주.
  2. 가로채기 된 메서드 내에서 ICorProfilerInfo 호출은 asynchronous로 간주. (예를 들어, 프로파일러가 정의한 함수를 호출하도록 IL 코드를 변경해서 호출되는 경우가 있다면, 프로파일러가 제공한 함수 내에서 ICorProfilerInfo의 함수를 호출하면 안 됨)
  3. FunctionIDMapper 후킹 코드 내에서 ICorProfilerInfo 호출하는 것은 asynchronous로 간주.
  4. 프로파일러 모듈이 직접 만든 스레드가 ICorProfilerInfo를 호출하는 것은 안전하게 synchronous로 간주. 왜냐하면, 그 스레드 상에서 CLR 내부로 재진입하는 등의 작업은 아무런 충돌 위험이 없기 때문.
  5. DoStackSnapshot을 호출한 상황이 synchronous였다면, 그것의 StackSnapshotCallback 콜백 함수 내에서의 ICorProfilerInfo 호출은 안전하게 synchronous로 간주.





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







[최초 등록일: ]
[최종 수정일: 11/8/2016]

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

비밀번호

댓글 작성자
 




... [106]  107  108  109  110  111  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11274정성태8/22/201719317.NET Framework: 674. Thread 타입의 Suspend/Resume/Join 사용 관련 예외 처리
11273정성태8/22/201721624오류 유형: 415. 윈도우 업데이트 에러 Error 0x80070643
11272정성태8/21/201724746VS.NET IDE: 120. 비주얼 스튜디오 2017 버전 15.3.1 - C# 7.1 공개 [2]
11271정성태8/19/201719166VS.NET IDE: 119. Visual Studio 2017에서 .NET Core 2.0 프로젝트 환경 구성하는 방법
11270정성태8/17/201730611.NET Framework: 673. C#에서 enum을 boxing 없이 int로 변환하기 [2]
11269정성태8/17/201721414디버깅 기술: 93. windbg - 풀 덤프에서 .NET 스레드의 상태를 알아내는 방법
11268정성태8/14/201720996디버깅 기술: 92. windbg - C# Monitor Lock을 획득하고 있는 스레드 찾는 방법
11267정성태8/10/201725074.NET Framework: 672. 모노 개발 환경
11266정성태8/10/201724864.NET Framework: 671. C# 6.0 이상의 소스 코드를 Visual Studio 설치 없이 명령행에서 컴파일하는 방법
11265정성태8/10/201753124기타: 66. 도서: 시작하세요! C# 7.1 프로그래밍: 기본 문법부터 실전 예제까지 [11]
11264정성태8/9/201724004오류 유형: 414. UWP app을 signtool.exe로 서명 시 0x8007000b 오류 발생
11263정성태8/9/201719472오류 유형: 413. The C# project "..." is targeting ".NETFramework, Version=v4.0", which is not installed on this machine. [3]
11262정성태8/5/201718203오류 유형: 412. windbg - SOS does not support the current target architecture. [3]
11261정성태8/4/201720776디버깅 기술: 91. windbg - 풀 덤프 파일로부터 강력한 이름의 어셈블리 추출 후 사용하는 방법
11260정성태8/3/201718868.NET Framework: 670. C# - 실행 파일로부터 공개키를 추출하는 방법
11259정성태8/2/201718128.NET Framework: 669. 지연 서명된 어셈블리를 sn.exe -Vr 등록 없이 사용하는 방법
11258정성태8/1/201718892.NET Framework: 668. 지연 서명된 DLL과 서명된 DLL의 차이점파일 다운로드1
11257정성태7/31/201719128.NET Framework: 667. bypassTrustedAppStrongNames 옵션 설명파일 다운로드1
11256정성태7/25/201720580디버깅 기술: 90. windbg의 lm 명령으로 보이지 않는 .NET 4.0 ClassLibrary를 명시적으로 로드하는 방법 [1]
11255정성태7/18/201723161디버깅 기술: 89. Win32 Debug CRT Heap Internals의 0xBAADF00D 표시 재현 [1]파일 다운로드3
11254정성태7/17/201719475개발 환경 구성: 322. "Visual Studio Emulator for Android" 에뮬레이터를 "Android Studio"와 함께 쓰는 방법
11253정성태7/17/201719743Math: 21. "Coding the Matrix" 문제 2.5.1 풀이 [1]파일 다운로드1
11252정성태7/13/201718413오류 유형: 411. RTVS 또는 PTVS 실행 시 Could not load type 'Microsoft.VisualStudio.InteractiveWindow.Shell.IVsInteractiveWindowFactory2'
11251정성태7/13/201717063디버깅 기술: 88. windbg 분석 - webengine4.dll의 MgdExplicitFlush에서 발생한 System.AccessViolationException의 crash 문제 (2)
11250정성태7/13/201720662디버깅 기술: 87. windbg 분석 - webengine4.dll의 MgdExplicitFlush에서 발생한 System.AccessViolationException의 crash 문제 [1]
11249정성태7/12/201718455오류 유형: 410. LoadLibrary("[...].dll") failed - The specified procedure could not be found.
... [106]  107  108  109  110  111  112  113  114  115  116  117  118  119  120  ...