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분
정성태

... 16  17  18  19  20  21  22  23  24  [25]  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13009정성태3/20/20227473개발 환경 구성: 640. docker - ibmcom/db2 컨테이너 실행
13008정성태3/19/20226757VS.NET IDE: 176. 비주얼 스튜디오 - 솔루션 탐색기에서 프로젝트를 선택할 때 csproj 파일이 열리지 않도록 만드는 방법
13007정성태3/18/20226328.NET Framework: 1181. C# - Oracle.ManagedDataAccess의 Pool 및 그것의 연결 개체 수를 알아내는 방법파일 다운로드1
13006정성태3/17/20227436.NET Framework: 1180. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 remuxing.c 예제 포팅
13005정성태3/17/20226236오류 유형: 800. C# - System.InvalidOperationException: Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.
13004정성태3/16/20226226디버깅 기술: 182. windbg - 닷넷 메모리 덤프에서 AppDomain에 걸친 정적(static) 필드 값을 조사하는 방법
13003정성태3/15/20226391.NET Framework: 1179. C# - (.NET Framework를 위한) Oracle.ManagedDataAccess 패키지의 성능 카운터 설정 방법
13002정성태3/14/20227180.NET Framework: 1178. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 http_multiclient.c 예제 포팅
13001정성태3/13/20227531.NET Framework: 1177. C# - 닷넷에서 허용하는 메서드의 매개변수와 호출 인자의 최대 수
13000정성태3/12/20227138.NET Framework: 1176. C# - Oracle.ManagedDataAccess.Core의 성능 카운터 설정 방법
12999정성태3/10/20226643.NET Framework: 1175. Visual Studio - 프로젝트 또는 솔루션의 Clean 작업 시 응용 프로그램에서 생성한 파일을 함께 삭제파일 다운로드1
12998정성태3/10/20226201.NET Framework: 1174. C# - ELEMENT_TYPE_FNPTR 유형의 사용 예
12997정성태3/10/202210647오류 유형: 799. Oracle.ManagedDataAccess - "ORA-01882: timezone region not found" 오류가 발생하는 이유
12996정성태3/9/202215731VS.NET IDE: 175. Visual Studio - 인텔리센스에서 오버로드 메서드를 키보드로 선택하는 방법
12995정성태3/8/20228093.NET Framework: 1173. .NET에서 Producer/Consumer를 구현한 BlockingCollection<T>
12994정성태3/8/20227351오류 유형: 798. WinDbg - Failed to load data access module, 0x80004002
12993정성태3/4/20227163.NET Framework: 1172. .NET에서 Producer/Consumer를 구현하는 기초 인터페이스 - IProducerConsumerCollection<T>
12992정성태3/3/20228627.NET Framework: 1171. C# - BouncyCastle을 사용한 암호화/복호화 예제파일 다운로드1
12991정성태3/2/20227784.NET Framework: 1170. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 transcode_aac.c 예제 포팅
12990정성태3/2/20227468오류 유형: 797. msbuild - The BaseOutputPath/OutputPath property is not set for project '[...].vcxproj'
12989정성태3/2/20226956오류 유형: 796. mstest.exe - System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.QualityTools.Tips.WebLoadTest.Tip
12988정성태3/2/20225931오류 유형: 795. CI 환경에서 Docker build 시 csproj의 Link 파일에 대한 빌드 오류
12987정성태3/1/20227433.NET Framework: 1169. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 demuxing_decoding.c 예제 포팅
12986정성태2/28/20228232.NET Framework: 1168. C# -IIncrementalGenerator를 적용한 Version 2 Source Generator 실습 [1]
12985정성태2/28/20228139.NET Framework: 1167. C# -Version 1 Source Generator 실습
12984정성태2/24/20227211.NET Framework: 1166. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 filtering_video.c 예제 포팅
... 16  17  18  19  20  21  22  23  24  [25]  26  27  28  29  30  ...