Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 7개 있습니다.)
개발 환경 구성: 401. .NET Core 콘솔 응용 프로그램을 배포(publish) 시 docker image 자동 생성
; https://www.sysnet.pe.kr/2/0/11708

개발 환경 구성: 402. .NET Core 콘솔 응용 프로그램을 docker로 실행/디버깅하는 방법
; https://www.sysnet.pe.kr/2/0/11709

VS.NET IDE: 143. Visual Studio - ASP.NET Core Web Application의 "Enable Docker Support" 옵션으로 달라지는 점
; https://www.sysnet.pe.kr/2/0/12171

VS.NET IDE: 144. .NET Core 콘솔 응용 프로그램을 배포(publish) 시 docker image 자동 생성 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/12197

VS.NET IDE: 185. Visual Studio - 원격 Docker container 내에 실행 중인 응용 프로그램에 대한 디버깅
; https://www.sysnet.pe.kr/2/0/13351

닷넷: 2156. .NET 7 이상의 콘솔 프로그램을 (dockerfile 없이) 로컬 docker에 배포하는 방법
; https://www.sysnet.pe.kr/2/0/13437

개발 환경 구성: 704. Visual Studio - .NET 8 프로젝트부터 dockerfile에 추가된 "USER app" 설정
; https://www.sysnet.pe.kr/2/0/13547




Visual Studio - 원격 Docker container 내에 실행 중인 응용 프로그램에 대한 디버깅

오호~~~ 아주 훌륭한 기능이 있군요. ^^ 공식 문서에 그 방법을 자세하게 설명하고 있습니다.

Attach to a process running on a Docker container
; https://learn.microsoft.com/en-us/visualstudio/debugger/attach-to-process-running-in-docker-container

제 경우에, 특정 container에서 실행 중인 응용 프로그램이, (다른 container에 있는 것은 잘 동작하는데) 그것만 문제가 발생해서 디버깅을 해야만 했습니다.

처음에는, 덤프를 떠서 분석하려고 했는데요, 해당 예제가 .NET Core 2.1이어서 (3.1부터 가능한) dotnet-dump를 사용할 수 없어 lldb로 덤프를 남기면 약 60GB가 나왔습니다. ^^;

그러다 위의 문서를 통해 원격 docker container에도 Process Attach 기능이 있다는 것을 알게 되었는데요, 방법이 매우 쉽습니다. 문서에 따라, docker를 호스팅하는 Linux 서버에 SSH 서버만 설치해 주면 됩니다. (대부분의 Linux 서버는 기본적으로 설치가 돼 있습니다.)

$ sudo apt-get install openssh-server unzip curl

이후에는 Visual Studio에서 "Debug" / "Attach to Process..." 메뉴를 선택해 뜨는 창에서 "Connection type"을 "Docker (Linux Container)"로 선택한 다음 "Connection target"의 "Find" 버튼을 누르면 "Select Docker Container" 창이 뜹니다.

거기서 SSH 서버가 실행 중인 (docker를 호스팅하는) 리눅스 머신에 대한 접속 정보를 추가해 주면,

ssh_container_dbg_2.png

Visual Studio가 해당 정보를 이용해 리눅스 머신에 접속한 후 docker로 운영 중인 컨테이너 목록을 나열합니다.

ssh_container_dbg_3.png

이후 디버깅을 원하는 응용 프로그램을 호스팅 중인 컨테이너 항목을 선택하면, 다음과 같이 그 컨테이너에서 실행 중인 .NET 프로세스를 나열해 줍니다.

ssh_container_dbg_4.png

위의 조건에서 "Attach to:"를 반드시 "Managed (.NET Core for Unix) code"로 선택한 후 해당 프로세스를 "Attach" 버튼을 눌러 연결하면 이제부터 Visual Studio가 디버깅 모드로 진입합니다.




이제 Visual Studio 내에 해당 컨테이너에서 운영 중인 응용 프로그램의 소스코드를 열어 Breakpoint를 걸면서 디버깅을 하시면 됩니다. 그런데, 대개의 경우 BP를 걸고 싶어도 다음과 같이 안 될 것입니다.

ssh_container_dbg_5.png

Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

The breakpoint will not currently be hit. No symbols have been loaded for this document.

따라서 "Debug" / "Optinos" 창에서 다음과 같이 "Enable Just My Code" 옵션을 꺼줍니다.

ssh_container_dbg_1.png

Off - Enable Just My Code

그럼 정상적으로 BP도 걸리고, 응용 프로그램 내에서 예외가 발생하면 Output 창에 "Exception thrown"도 뜨게 될 것입니다. 예외가 발생한 코드를 알고 싶다면 Ctrl+Alt+E 키를 눌러 "Exception Settings" 창에서 해당 예외, 예를 들어 "Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Http.dll" 이렇게 발생하고 있다면 다음과 같이 "System.InvalidOperationException" 예외를 검색해 Check 해주면,

ssh_container_dbg_6.png

위의 화면과 같이 자동으로 예외가 발생한 소스코드 창을 열어 해당 라인에서 BP가 걸리게 됩니다. 아울러, 좌측 하단의 Locals 창에는 일부 변수의 값을 확인하는 것도 가능합니다. 모든 값이 나오진 않고 일부는 "Cannot obtain value of the local variable or argument because it is not available at this instruction pointer, possibly because it has been optimized away."라는 메시지로 값이 구해지지 않는데요, 이에 대해서는 Release 관련한 최적화 작업이 관여한 것이므로,

소스 코드가 없는 닷넷 어셈블리를 디버깅할 때 지역 변숫값을 확인하는 방법
; https://www.sysnet.pe.kr/2/0/11036

어쩔 수 없습니다. 그래도, 저만큼이라도 Live 디버깅이 되면 아마도 대부분의 문제는 디버깅이 가능할 것입니다. ^^

그나저나, 방법만으로 보면 윈도우 환경에서는 Remote Debugging Tools도 설치해야 하는 번거로움이 있으니 오히려 리눅스에서의 원격 디버깅이 더 편합니다. ^^;




간혹 Attach 했을 때 다음과 같은 메시지와 함께 실패할 때가 있습니다.

Failed to launch debug adapter.  Additional information may be available in the output window.

Could not create the shell, a connectivity error has occured.

Client not connected.

Failed to launch debug adapter 'coreclr'.

제 경우에는 그냥 무시하고 재차 Attach를 했더니 정상적으로 연결이 됐습니다.




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







[최초 등록일: ]
[최종 수정일: 6/21/2023]

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

비밀번호

댓글 작성자
 



2023-05-19 09시22분
정성태

1  2  3  4  5  6  7  8  9  10  11  12  [13]  14  15  ...
NoWriterDateCnt.TitleFile(s)
13314정성태4/9/20234013개발 환경 구성: 672. DosBox를 이용한 Turbo C, Windows 3.1 설치
13313정성태4/9/20234036개발 환경 구성: 671. Hyper-V VM에 Turbo C 2.0 설치 [2]
13312정성태4/8/20234095Windows: 244. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (개선된 버전)파일 다운로드1
13311정성태4/7/20234554C/C++: 163. Visual Studio 2022 - DirectShow 예제 컴파일(WAV Dest)
13310정성태4/6/20234212C/C++: 162. Visual Studio - /NODEFAULTLIB 옵션 설정 후 수동으로 추가해야 할 library
13309정성태4/5/20234333.NET Framework: 2107. .NET 6+ FileStream의 구조 변화
13308정성태4/4/20234240스크립트: 47. 파이썬의 time.time() 실숫값을 GoLang / C#에서 사용하는 방법
13307정성태4/4/20233990.NET Framework: 2106. C# - .NET Core/5+ 환경의 Windows Forms 응용 프로그램에서 HINSTANCE 구하는 방법
13306정성태4/3/20233783Windows: 243. Win32 - 윈도우(cbWndExtra) 및 윈도우 클래스(cbClsExtra) 저장소 사용 방법
13305정성태4/1/20234166Windows: 242. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (쉬운 버전)파일 다운로드1
13304정성태3/31/20234482VS.NET IDE: 181. Visual Studio - C/C++ 프로젝트에 application manifest 적용하는 방법
13303정성태3/30/20233838Windows: 241. 환경 변수 %PATH%에 DLL을 찾는 규칙
13302정성태3/30/20234468Windows: 240. RDP 환경에서 바뀌는 %TEMP% 디렉터리 경로
13301정성태3/29/20234588Windows: 239. C/C++ - Windows 10 Version 1607부터 지원하는 /DEPENDENTLOADFLAG 옵션파일 다운로드1
13300정성태3/28/20234241Windows: 238. Win32 - Modal UI 창에 올바른 Owner(HWND)를 설정해야 하는 이유
13299정성태3/27/20233999Windows: 237. Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지
13298정성태3/27/20233984Windows: 236. Win32 - MessageBeep 소리가 안 들린다면?
13297정성태3/26/20234650Windows: 235. Win32 - Code Modal과 UI Modal
13296정성태3/25/20233988Windows: 234. IsDialogMessage와 협업하는 WM_GETDLGCODE Win32 메시지 [1]파일 다운로드1
13295정성태3/24/20234242Windows: 233. Win32 - modeless 대화창을 modal처럼 동작하게 만드는 방법파일 다운로드1
13294정성태3/22/20234425.NET Framework: 2105. LargeAddressAware 옵션이 적용된 닷넷 32비트 프로세스의 가용 메모리 - 두 번째
13293정성태3/22/20234487오류 유형: 853. dumpbin - warning LNK4048: Invalid format file; ignored
13292정성태3/21/20234596Windows: 232. C/C++ - 일반 창에도 사용 가능한 IsDialogMessage파일 다운로드1
13291정성태3/20/20234970.NET Framework: 2104. C# Windows Forms - WndProc 재정의와 IMessageFilter 사용 시의 차이점
13290정성태3/19/20234456.NET Framework: 2103. C# - 윈도우에서 기본 제공하는 FindText 대화창 사용법파일 다운로드1
13289정성태3/18/20233672Windows: 231. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 자식 윈도우를 생성하는 방법파일 다운로드1
1  2  3  4  5  6  7  8  9  10  11  12  [13]  14  15  ...