Microsoft MVP성태의 닷넷 이야기
디버깅 기술: 1. 디버깅 방법 - CLR 프로파일러 [링크 복사], [링크+제목 복사],
조회: 29455
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 2개 있습니다.)

저 같은 경우, 해당 응용 프로그램을 개발하기 쉬운지, 어려운지에 대한 기준으로 얼마나 쉽게 "디버거" 환경에서 구동시킬 수 있느냐로 판단합니다. 쉽게 말해서, IDE 환경에서 "F5"를 통한 디버깅이 되느냐/안되느냐에 따른 것인데요.

그러한 디버깅이 다소 어려운 Windows Shell, ISAPI Filter, API 후킹 등은 "어려운 분야"라고 저는 판단합니다. 사실 어려운 분야죠. ^^; 어려울수록 디버깅은 더욱 힘들어지는 것이 정석인가 봅니다.

다행스러운 것은, 최근 들어 전체적으로 개발환경이 .NET으로 넘어오면서, "F5 디버깅"의 영역이 넓어지고 있다는 것입니다. 단적인 예로, ASP.NET 디버깅이 그렇죠.



이런저런 이유로, 어떤 응용 프로그램을 개발할 때에 저는 최대한 "F5 디버깅"이 가능하게 하려고 노력을 합니다. 이번 글은, 최근에 제가 노력했었던 "F5 디버깅" 환경 구성 중에서 "CLR 프로파일러"를 위한 것을 설명하겠습니다.

CLR 프로파일러 자체는 Unamaged C/C++로 개발이 되고, Managed 환경으로부터의 접점을 Environment Variable을 통해서 하고 있습니다. 얼핏 디버깅 방법이 실행 중에 attach 시키는 것뿐이 없는 것 같은데요. 그런 식으로 디버깅하는 것과 "F5 디버깅"의 생산성 차이는 엄청나기 때문에 조금 살펴보게 되었습니다.

일단, 시작 예제 프로젝트는 7차 MMS 모임 때 발표 자료였던 "High-Level .NET Profiling API"를 이용한 프로젝트로 하겠습니다.어차피 Low-Level CLR Profiling API도 마찬가지일거라 봅니다. 관련 자료는 다음의 URL에서 찾아 볼 수 있습니다.

.NET Profiling
Write Profilers With Ease Using High-Level Wrapper Classes
; https://docs.microsoft.com/en-us/archive/msdn-magazine/2006/april/write-profilers-with-ease-using-high-level-wrapper-classes

이제부터, .NET Profiler 프로젝트를 위한 디버깅 환경 설정을 설명해 보겠습니다.

1. 우선, 프로젝트 설정 / "General" 범주에서 "Output Directory"를 CLR Profiling 대상이 되는 .NET 프로그램이 있는 폴더로 지정합니다. 당연하겠지요. ^^

다음은 실제 예제 프로젝트의 솔루션 구조와, 대상 Output Directory에 모여진 파일들의 모습입니다.
Output Directory

2. "Debugging" 범주에서 아래와 같이 적절한 값으로 Command, Working Directory, Debugger Type을 지정합니다. Command Arguments가 있는 경우에는 역시 입력해 주면 되겠고, 각자 자신이 맞는 환경에 맞게 값을 채워주시면 됩니다. 주의할 것은 Working Directory도 반드시 명시를 해주셔야 합니다.

  Command : .NET 프로파일링 대상이 되는 EXE 프로그램 경로
  Working Directory : 대상 EXE 프로그램이 있는 디렉터리
  Debugger Type : 반드시 Native Only 값을 주어야 합니다. Mixed 방식을 주면 CLR로부터의 Call back API들에서 Break Point가 동작하지 않습니다.

프로젝트 설정 화면

3. 이미 말씀드린 것처럼, CLR Profiling의 동작 방식은 CLR이 로딩시에 환경 변수에 특정 변수로 등록된 COM 개체의 CLSID를 얻어서 해당 COM 개체를 활성화시킨 다음 정해진 interface 규칙에 맞게 callback을 해주는 구조입니다. 따라서, "F5 디버깅"을 위해서는 해당 디버깅 세션 동안에 유효할 수 있는 환경 변수 설정을 적절하게 해주어야 합니다. 사실 VS.NET 2003까지는 디버깅 세션에 환경 변수를 설정할 수 있는 방법이 없었습니다. "My Computer"의 전역 환경 설정 변수를 이용할 수도 있었겠지만, 그런 경우 전체 응용 프로그램 모두에 프로파일링 API가 동작하게 되는 부작용이 있으므로 사용하기에는 현실성이 없어 보입니다.

다행히도, VS.NET 2005에서는 디버깅 세션에 환경 변수를 설정할 수 있는 방법을 명시적으로 제공하고 있습니다. 아래의 화면에서 보는 것처럼, CLR 프로파일링 동작을 위한 환경 변수를 설정해 주시면 됩니다.

환경 변수 설정

4. 자, 이제 모든 준비는 끝났습니다. 평상시처럼, 자신이 구현한 CLR 프로파일러 내부의 로직에 break point를 설정한 후, "F5" 키를 누르면 아래 화면과 같이 정상적으로 디버깅이 가능한 것을 볼 수 있습니다.

CLR 프로파일러 디버깅 화면 **** 첨부 파일은 이 글에서 설명한 예제 프로젝트입니다.
[연관 글]






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

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

비밀번호

댓글 작성자
 



2012-09-20 12시39분
본문과는 상관없지만! 프로파일러와 관련이 있어서 기록을 남깁니다.

ICorProfilerInfo2::DoStackSnapshot 호출의 반환값(hr)으로 E_INVALIDARG (-2147024809, 0x80070057) 값이 나왔다면? DoStackSnapshot API가 동작하기 위해서는 ICorProfilerInfo2::SetEventMask에 COR_PRF_ENABLE_STACK_SNAPSHOT 옵션을 주어야 하기 때문입니다.
정성태

... 106  107  [108]  109  110  111  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11258정성태8/1/201720314.NET Framework: 668. 지연 서명된 DLL과 서명된 DLL의 차이점파일 다운로드1
11257정성태7/31/201719898.NET Framework: 667. bypassTrustedAppStrongNames 옵션 설명파일 다운로드1
11256정성태7/25/201721832디버깅 기술: 90. windbg의 lm 명령으로 보이지 않는 .NET 4.0 ClassLibrary를 명시적으로 로드하는 방법 [1]
11255정성태7/18/201724343디버깅 기술: 89. Win32 Debug CRT Heap Internals의 0xBAADF00D 표시 재현 [1]파일 다운로드3
11254정성태7/17/201720767개발 환경 구성: 322. "Visual Studio Emulator for Android" 에뮬레이터를 "Android Studio"와 함께 쓰는 방법
11253정성태7/17/201721404Math: 21. "Coding the Matrix" 문제 2.5.1 풀이 [1]파일 다운로드1
11252정성태7/13/201719134오류 유형: 411. RTVS 또는 PTVS 실행 시 Could not load type 'Microsoft.VisualStudio.InteractiveWindow.Shell.IVsInteractiveWindowFactory2'
11251정성태7/13/201718624디버깅 기술: 88. windbg 분석 - webengine4.dll의 MgdExplicitFlush에서 발생한 System.AccessViolationException의 crash 문제 (2)
11250정성태7/13/201722215디버깅 기술: 87. windbg 분석 - webengine4.dll의 MgdExplicitFlush에서 발생한 System.AccessViolationException의 crash 문제 [1]
11249정성태7/12/201719964오류 유형: 410. LoadLibrary("[...].dll") failed - The specified procedure could not be found.
11248정성태7/12/201726520오류 유형: 409. pip install pefile - 'cp949' codec can't decode byte 0xe2 in position 208687: illegal multibyte sequence
11247정성태7/12/201720839오류 유형: 408. SqlConnection 객체 생성 시 무한 대기 문제파일 다운로드1
11246정성태7/11/201718884VS.NET IDE: 118. Visual Studio - 다중 폴더에 포함된 파일들에 대한 "Copy to Output Directory"를 한 번에 설정하는 방법
11245정성태7/10/201724628개발 환경 구성: 321. Visual Studio Emulator for Android 소개 [2]
11244정성태7/10/201724814오류 유형: 407. Visual Studio에서 ASP.NET Core 실행할 때 dotnet.exe 프로세스의 -532462766 오류 발생 [1]
11243정성태7/10/201721591.NET Framework: 666. dotnet.exe - 윈도우 운영체제에서의 .NET Core 버전 찾기 규칙
11242정성태7/8/201721129제니퍼 .NET: 27. 제니퍼 닷넷 적용 사례 (7) - 노후된 스토리지 장비로 인한 웹 서비스 Hang (멈춤) 현상
11241정성태7/8/201719777오류 유형: 406. Xamarin 빌드 에러 XA5209, APT0000
11240정성태7/7/201723593.NET Framework: 665. ClickOnce를 웹 브라우저를 이용하지 않고 쿼리 문자열을 전달하면서 실행하는 방법 [3]파일 다운로드1
11239정성태7/6/201724249.NET Framework: 664. Protocol Handler - 웹 브라우저에서 데스크톱 응용 프로그램을 실행하는 방법 [5]파일 다운로드1
11238정성태7/6/201721776오류 유형: 405. NT 서비스 시작 시 "Error 1067: The process terminated unexpectedly." 오류 발생 [2]
11237정성태7/5/201723435.NET Framework: 663. C# - PDB 파일 경로를 PE 파일로부터 얻는 방법파일 다운로드1
11236정성태7/4/201727162.NET Framework: 662. C# - VHD/VHDX 가상 디스크를 마운트하지 않고 파일을 복사하는 방법파일 다운로드1
11235정성태6/29/201721396Math: 20. Matlab/Octave로 Gram-Schmidt 정규 직교 집합 구하는 방법
11234정성태6/29/201718870오류 유형: 404. SharePoint 2013 설치 과정에서 "The username is invalid The account must be a valid domain account" 오류 발생
11233정성태6/28/201718777오류 유형: 403. SharePoint Server 2013을 Windows Server 2016에 설치할 때 .NET 4.5 설치 오류 발생
... 106  107  [108]  109  110  111  112  113  114  115  116  117  118  119  120  ...