Microsoft MVP성태의 닷넷 이야기
VS.NET IDE: 63. Visual Studio 2010 - Parallel Stacks [링크 복사], [링크+제목 복사],
조회: 27313
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

Visual Studio 2010 - Parallel Stacks


Parallel Stacks - another new VS2010 debugger window 
; http://www.danielmoth.com/Blog/Parallel-Stacks-Another-New-VS2010-Debugger-Window.aspx

오... 멋집니다. 다중 스레드의 생성 흐름을 시각적으로 보여줍니다.

일례로 [그림 1]은 WPF 응용 프로그램 실행 시에 Application::OnStartup 이벤트에서 디버거 중단점을 잡고 "Debug" / "Windows" / "Parallel Stacks" 뷰를 선택한 것입니다. 기본 설정으로는 "Tools" / "Options" / "Debugging" - "Enable Just My Code" 옵션을 켠 상태의 콜 스택 뷰처럼 로드된 프로젝트와 소스 코드가 연관된 다이어그램으로 제한해서 보여줍니다. 만약 "Enable Just My Code"를 끈 효과를 내려면 "Parallel Stacks" 뷰의 오른쪽 버튼 메뉴에서 "Show External Code"를 선택하면 다음과 같이 자세하게 나옵니다.

[그림 1: 새로 추가된 Parallel Stacks 뷰]
vs2010_Parallel_Stacks_view_1.png

해석하는 방법은 간단합니다. 맨 아래에 있는 "파란색 상자"를 실행하는 스레드가 최초 실행이 되었는데, 거기서 스레드를 3개 생성한 것입니다. 각각의 다이어그램에 있는 "n Threads" 위에 마우스를 올리면 관련 스레드의 ID를 알아낼 수 있습니다.

[그림 2: 스레드 ID 확인]
vs2010_Parallel_Stacks_view_2.png

또한, 현재 "Call Stack" 뷰에서 다뤄지고 있는 스레드가 어떤 스레드인지를 "파란색 화살표"와 "파란색 상자"를 통해서 알 수 있습니다. 나머지 회색 상자는 실행은 되고 있지만 현재 디버깅 대상으로 선택되지 않은 스레드(즉, Call stack에 나타나지 않는 스레드)임을 나타냅니다.

[그림 3: 검은색 화살표와 회색 상자 - 현재 선택된 스레드가 아님]
vs2010_Parallel_Stacks_view_3.png

[그림 4: 파란색 화살표와 파란 상자 - 선택된 스레드]
vs2010_Parallel_Stacks_view_4.png

메서드 옆에 나타나는 3개의 아이콘에 대해서도 설명을 하고 있는데, 의미는 "Call Stack"과 연계해서 보면 그리 어렵지 않게 알 수 있습니다.

[그림 5: 노란색 화살표 - 현재 스레드의 활성화된 스택 프레임]
vs2010_Parallel_Stacks_view_5.png

즉, 노란색 화살표는 "디버깅 대상으로 선택된 스레드"가 실행하고 있는 코드를 담은 메서드임을 알려줍니다.

반면에 녹색 화살표는 "디버깅 대상으로 선택된 스레드"의 스택 프레임 중에 있는 메서드를 나타냅니다. 쉽게 생각해서 "Call Stack" 뷰에서 "노란색 화살표"가 있는 메서드를 실행하기까지 거쳐온 콜 스택의 한 메서드임을 알려줍니다. 사실, ^^ 별다르게 새로울 것이 없는 데 이미 기존에도 아래와 같이 노란색 화살표와 녹색 화살표가 동일하게 사용되어져 왔습니다.

[그림 6: Call Stack에서와 동일한 의미의 녹색 화살표]
vs2010_Parallel_Stacks_view_6.png

마지막으로 물결 모양 아이콘(Cloth Icon이라고 써있지만.)도 있는 데, 디버깅 대상으로 선택되어 있지 않은 스레드들이 실행하고 있는 메서드의 스택 프레임을 가리킵니다.

[그림 7: 물결 모양 아이콘 - 활성화된 스택 프레임]
vs2010_Parallel_Stacks_view_7.png

이 정도면, 대략 눈에 익어지셨나요?

멀티 스레드 응용 프로그램을 위한 디버깅 도구를 Visual Studio 2010에서 제대로 지원해 주고 있군요. 두말할 것도 없이, 스레드 호출 관계의 시각화는 정말 반가운 기능입니다.




사용하다 보니, 한 가지 아쉬운 점이 있는데요.

[그림 6]에서 보면 "Parallel Stacks" 뷰가 "Enable Just My Code"가 꺼진 것과 동일하게 모든 호출 스택 프레임을 보여주고 있습니다. 사실 "Show External Code" 메뉴와 "Enable Just My Code" 설정은 동일한 역할을 합니다. 그렇기 때문에 차라리 이 부분은 "Enable Just My Code"로 통합하면 좋았을 것 같습니다.

아쉬움을 넘어서 문제가 되는 부분도 있습니다. "Parallel Stacks" 뷰에서 선택한 "Show External Code" 설정이 "Parallel Stacks" 뷰를 닫은 상태에서도 유효하다는 것입니다. 심지어 프로젝트를 닫고 다시 열어도 "Call Stack"뷰는 "Enable Just My Code"가 켜져 있음에도 불구하고 여전히 모든 스택 프레임을 보여줍니다.

누가 이 부분에 대해 벌써 ^^ Bug Feedback을 제출해 놓았군요.

"Enable Just My Code" is turned off when "Show External Code" is checked once.
; https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=456565



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

[연관 글]






[최초 등록일: ]
[최종 수정일: 8/7/2021]

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

비밀번호

댓글 작성자
 



2021-08-07 09시38분
Visual Studio 2019로 디버깅 시 "Command" 창에 "Debug.ListCallStacks -AllThreads" 명령어를 수행하면 모든 스레드의 호출 스택을 출력합니다. 해당 명령어를 타이핑할 때 인텔리센스를 지원해서 입력이 실제로는 그다지 부담스럽지 않은데요, 그래도 저 명령어를 굳이 수행할 필요는 없을 것 같습니다.

왜냐하면, windbg의 명령어에서 모든 스레드의 호출 스택을 보여주는 "~*k" 명령어를 비주얼 스튜디오의 Command 창에서도 유사하게 제공을 하는데, 이것의 출력 결과가 "Debug.ListCallStacks -AllThreads"와 정확하게 일치합니다. 따라서, 길게 명령어 입력할 필요없이 그냥 "~*k"라고 치면 됩니다.
정성태

... 46  47  48  [49]  50  51  52  53  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
12715정성태7/17/202122512오류 유형: 736. Windows - MySQL zip 파일 버전의 "mysqld --skip-grant-tables" 실행 시 비정상 종료 [1]
12714정성태7/16/202115923오류 유형: 735. VCRUNTIME140.dll, MSVCP140.dll, VCRUNTIME140.dll, VCRUNTIME140_1.dll이 없어 exe 실행이 안 되는 경우
12713정성태7/16/202117313.NET Framework: 1077. C# - 동기 방식이면서 비동기 규약을 따르게 만드는 Task.FromResult파일 다운로드1
12712정성태7/15/202116264개발 환경 구성: 579. Azure - 리눅스 호스팅의 Site Extension 제작 방법
12711정성태7/15/202116228개발 환경 구성: 578. Azure - Java Web App Service를 위한 Site Extension 제작 방법
12710정성태7/15/202118876개발 환경 구성: 577. MQTT - emqx.io 서비스 소개
12709정성태7/14/202114413Linux: 42. 실행 중인 docker 컨테이너에 대한 구동 시점의 docker run 명령어를 확인하는 방법
12708정성태7/14/202118673Linux: 41. 리눅스 환경에서 디스크 용량 부족 시 원인 분석 방법
12707정성태7/14/202185825오류 유형: 734. MySQL - Authentication method 'caching_sha2_password' not supported by any of the available plugins.
12706정성태7/14/202117015.NET Framework: 1076. C# - AsyncLocal 기능을 CallContext만으로 구현하는 방법 [2]파일 다운로드1
12705정성태7/13/202117465VS.NET IDE: 168. x64 DLL 프로젝트의 컨트롤이 Visual Studio의 Designer에서 보이지 않는 문제 - 두 번째 이야기
12704정성태7/12/202116203개발 환경 구성: 576. Azure VM의 서비스를 Azure Web App Service에서만 접근하도록 NSG 설정을 제한하는 방법
12703정성태7/11/202121564개발 환경 구성: 575. Azure VM에 (ICMP) ping을 허용하는 방법
12702정성태7/11/202117338오류 유형: 733. TaskScheduler에 등록된 wacs.exe의 Let's Encrypt 인증서 업데이트 문제
12701정성태7/9/202116842.NET Framework: 1075. C# - ThreadPool의 스레드는 반환 시 ThreadStatic과 AsyncLocal 값이 초기화 될까요?파일 다운로드1
12700정성태7/8/202117330.NET Framework: 1074. RuntimeType의 메모리 누수? [1]
12699정성태7/8/202115882VS.NET IDE: 167. Visual Studio 디버깅 중 GC Heap 상태를 보여주는 "Show Diagnostic Tools" 메뉴 사용법
12698정성태7/7/202120095오류 유형: 732. Windows 11 업데이트 시 3% 또는 0%에서 다운로드가 멈춘 경우
12697정성태7/7/202115161개발 환경 구성: 574. Windows 11 (Insider Preview) 설치하는 방법
12696정성태7/6/202116108VC++: 146. 운영체제의 스레드 문맥 교환(Context Switch)을 유사하게 구현하는 방법파일 다운로드2
12695정성태7/3/202116160VC++: 145. C 언어의 setjmp/longjmp 기능을 Thread Context를 이용해 유사하게 구현하는 방법파일 다운로드1
12694정성태7/2/202118118Java: 24. Azure - Spring Boot 앱을 Java SE(Embedded Web Server)로 호스팅 시 로그 파일 남기는 방법 [1]
12693정성태6/30/202115053오류 유형: 731. Azure Web App Site Extension - Failed to install web app extension [...]. {1}
12692정성태6/30/202115540디버깅 기술: 180. Azure - Web App의 비정상 종료 시 남겨지는 로그 확인
12691정성태6/30/202115717개발 환경 구성: 573. 테스트 용도이지만 테스트에 적합하지 않은 Azure D1 공유(shared) 요금제
12690정성태6/28/202116742Java: 23. Azure - 자바(Java)로 만드는 Web App Service - Tomcat 호스팅
... 46  47  48  [49]  50  51  52  53  54  55  56  57  58  59  60  ...