Microsoft MVP성태의 닷넷 이야기
.NET Framework: 621. 닷넷 프로파일러의 오류 코드 - 0x80131363 [링크 복사], [링크+제목 복사],
조회: 21840
글쓴 사람
정성태 (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

비밀번호

댓글 작성자
 




[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13917정성태4/30/202567VS.NET IDE: 199. Directory.Build.props에 정의한 속성에 대해 Condition 제약으로 값을 변경하는 방법
13916정성태4/23/2025472디버깅 기술: 221. WinDbg 분석 사례 - ASP.NET HttpCookieCollection을 다중 스레드에서 사용할 경우 무한 루프 현상 - 두 번째 이야기
13915정성태4/13/20251685닷넷: 2331. C# - 실행 시에 메서드 가로채기 (.NET 9)파일 다운로드1
13914정성태4/11/20251988디버깅 기술: 220. windbg 분석 사례 - x86 ASP.NET 웹 응용 프로그램의 CPU 100% 현상 (4)
13913정성태4/10/20251215오류 유형: 950. Process Explorer - 64비트 윈도우에서 32비트 프로세스의 덤프를 뜰 때 "Error writing dump file: Access is denied." 오류
13912정성태4/9/2025874닷넷: 2330. C# - 실행 시에 메서드 가로채기 (.NET 5 ~ .NET 8)파일 다운로드1
13911정성태4/8/20251116오류 유형: 949. WinDbg - .NET Core/5+ 응용 프로그램 디버깅 시 sos 확장을 자동으로 로드하지 못하는 문제
13910정성태4/8/20251266디버깅 기술: 219. WinDbg - 명령어 내에서 환경 변수 사용법
13909정성태4/7/20251775닷넷: 2329. C# - 실행 시에 메서드 가로채기 (.NET Framework 4.8)파일 다운로드1
13908정성태4/2/20252184닷넷: 2328. C# - MailKit: SMTP, POP3, IMAP 지원 라이브러리
13907정성태3/29/20251996VS.NET IDE: 198. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C# 프로젝트의 출력 경로 변경하기
13906정성태3/27/20252270닷넷: 2327. C# - 초기화되지 않은 메모리에 접근하는 버그?파일 다운로드1
13905정성태3/26/20252308Windows: 281. C++ - Windows / Critical Section의 안정화를 위해 도입된 "Keyed Event"파일 다운로드1
13904정성태3/25/20251916디버깅 기술: 218. Windbg로 살펴보는 Win32 Critical Section파일 다운로드1
13903정성태3/24/20251536VS.NET IDE: 197. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C++ 프로젝트의 출력 경로 변경하기
13902정성태3/24/20251748개발 환경 구성: 742. Oracle - 테스트용 hr 계정 및 데이터 생성파일 다운로드1
13901정성태3/9/20252138Windows: 280. Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root)
13900정성태3/8/20252362스크립트: 72. 파이썬 - SQLAlchemy + oracledb 연동
13899정성태3/7/20251835스크립트: 71. 파이썬 - asyncio의 ContextVar 전달
13898정성태3/5/20252158오류 유형: 948. Visual Studio - Proxy Authentication Required: dotnetfeed.blob.core.windows.net
13897정성태3/5/20252389닷넷: 2326. C# - PowerShell과 연동하는 방법 (두 번째 이야기)파일 다운로드1
13896정성태3/5/20252204Windows: 279. Hyper-V Manager - VM 목록의 CPU Usage 항목이 항상 0%로 나오는 문제
13895정성태3/4/20252248Linux: 117. eBPF / bpf2go - Map에 추가된 요소의 개수를 확인하는 방법
13894정성태2/28/20252287Linux: 116. eBPF / bpf2go - BTF Style Maps 정의 구문과 데이터 정렬 문제
13893정성태2/27/20252225Linux: 115. eBPF (bpf2go) - ARRAY / HASH map 기본 사용법
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...