25

Visual Studio (2005의 경우)에서 프로그램을 디버깅 할 때 "step over"(F10)를 실행하면 문제가 발생합니다 다음 코드 줄에서는 종종 내가보고있는 코드와 완전히 다른 스레드에서 코드의 특정 줄에 도달하게됩니다. 이것은 제가 한 일의 모든 맥락이 상실되었음을 의미합니다.Visual Studio에서 다중 스레드 프로그램을 디버깅 할 때 "스텝 오버"

어떻게 해결할 수 있습니까?

이후 버전의 Visual Studio에서 가능하면이를 잘 듣고 싶습니다. 단지이 스레드 중단에 대한 조건을 가지고 코드의 다음 줄에 중단 점을 설정

나는 그것이 너무 많은 일이 나를 위해 유용하게 :)

답변

37

귀하의 질문에 단 하나의 답변이 있다고 생각합니다. 귀하의 질문에 '너무 많은 작업'으로 할인되어 있습니다. 그러나 나는 그것이 잘못된 길로 가고 있다고 믿습니다. Thread ID에 조건부 중단 점을 추가하는 단계를 설명 하겠지만 매우 간단하지만 알기 전까지는 분명하지 않습니다.

  1. 당신이 디버깅을 계속하려면 올바른 스레드에있는 지점에서 디버거를 중지 (이 얻는 첫 번째 스레드는 일반적으로 생각 엔 것 입니다).

  2. 시계 창에 $TID을 입력하십시오.

  3. 는 식 창
    >,
    에서 $ TID의 상태 $TID == <값 중단 점을 추가 $TID == 0x000016a0

  4. 은 실행을 계속합니다.

$TID는 마이크로 소프트 컴파일러 마법의 변수 현재 스레드 ID의 값을 가진다 (스튜디오   2003   적어도 시각부터). 그것은 (FS + 0x18) [0x24]를 보는 것보다 훨씬 쉽게 만듭니다. = D

즉, 간단한 매크로를 사용하여 디버거의 원샷 중단 점과 동일한 동작을 얻을 수 있습니다. 단계를 넘기면 디버거가 백그라운드에서 중단 점을 설정하고 해당 중단 점을 실행 한 다음 제거합니다. 일관된 사용자 인터페이스의 핵심은 ANY 중단 점에 도달하면 해당 중단 점을 제거하는 것입니다.

다음 두 매크로는 현재 스레드 커서하려면 및 실행 이상 단계를 제공합니다. 이것은 디버거와 같은 방식으로 수행됩니다. 중단 점은 어떤 중단 점에 도달했는지에 관계없이 실행 후에 제거됩니다.

실행하려면 키 조합을 지정해야합니다.

참고 : 하나주의 - 커서가 당신이 이상의 단계로 원하는 라인에있는 경우 매크로 통해 단계는 제대로 작동합니다. 이는 커서 위치로 현재 위치를 판별하고 단순히 행 번호에 하나를 추가하기 때문입니다. 매크로 IDE에서 해당 정보를 찾을 수는 없지만 위치 계산을 현재 실행 지점의 정보로 바꿀 수 있습니다. 여기

들이는 행운 버그 사냥!

Visual Studio에서이 매크로를 사용하려면 :
1. 매크로 IDE (메뉴에서를 선택 도구 -> Macros-> 매크로 IDE ...)
2. 추가 새로운 코드 파일이 코드에
3. 붙여 넣기 (메뉴에서는 : 프로젝트 -이> ...을 새 항목을 추가 코드 파일 선택하고 추가를 클릭 : 선택).
4. 파일을 저장하십시오.

비주얼 스튜디오에서이 매크로를 실행하기위한 키 조합을 추가하려면 :
1. 옵션 (메뉴에서 선택 : 도구 -> 옵션)
2. 환경 -> 키보드로 확장
입력 매크로 : 포함 명령 표시
3.
모든 매크로를 볼 수 있습니다.
4. 매크로를 선택한 다음 을 눌러 바로 가기 키 클릭 :
5. 콤보 사용하려는 (백 스페이스가 삭제 입력 콤보)
6. 지정 실행하는 바로 가기를 설정합니다 선택된 매크로.
Imports System 
Imports EnvDTE 
Imports EnvDTE80 
Imports System.Diagnostics 

Public Module DebugHelperFunctions 

    Sub RunToCursorInMyThread() 
     Dim textSelection As EnvDTE.TextSelection 
     Dim myThread As EnvDTE.Thread 
     Dim bp As EnvDTE.Breakpoint 
     Dim bps As EnvDTE.Breakpoints 

     ' For Breakpoints.Add() 
     Dim FileName As String 
     Dim LineNumber As Integer 
     Dim ThreadID As String 

     ' Get local references for ease of use 
     myThread = DTE.Debugger.CurrentThread 
     textSelection = DTE.ActiveDocument.Selection 

     LineNumber = textSelection.ActivePoint.Line 
     FileName = textSelection.DTE.ActiveDocument.FullName 
     ThreadID = myThread.ID 

     ' Add a "One-Shot" Breakpoint in current file on current line for current thread 
     bps = DTE.Debugger.Breakpoints.Add("", FileName, LineNumber, 1, "$TID == " & ThreadID) 

     ' Run to the next stop 
     DTE.Debugger.Go(True) 

     ' Remove our "One-Shot" Breakpoint 
     For Each bp In bps 
      bp.Delete() 
     Next 
    End Sub 

    Sub StepOverInMyThread() 
     Dim textSelection As EnvDTE.TextSelection 
     Dim myThread As EnvDTE.Thread 
     Dim bp As EnvDTE.Breakpoint 
     Dim bps As EnvDTE.Breakpoints 

     ' For Breakpoints.Add() 
     Dim FileName As String 
     Dim LineNumber As Integer 
     Dim ThreadID As String 

     ' Get local references for ease of use 
     myThread = DTE.Debugger.CurrentThread 
     textSelection = DTE.ActiveDocument.Selection 

     LineNumber = textSelection.ActivePoint.Line 
     FileName = textSelection.DTE.ActiveDocument.FullName 
     ThreadID = myThread.ID 
     LineNumber = LineNumber + 1 

     ' Add a "One-Shot" Breakpoint in current file on current line for current thread 
     bps = DTE.Debugger.Breakpoints.Add("", FileName, LineNumber, 1, "$TID == " & ThreadID) 

     ' Run to the next stop 
     DTE.Debugger.Go(True) 

     ' Remove our "One-Shot" Breakpoint 
     For Each bp In bps 
      bp.Delete() 
     Next 
    End Sub 


End Module 

면책 조항

: 나는 비주얼 스튜디오 2005 이러한 매크로를 썼다. 아마 Visual Studio 2008에서 잘 사용할 수 있습니다. Visual Studio 2003
및 그 전에 수정하려면 이 필요할 수 있습니다. 하나 개의 특정 스레드를 디버깅하는

+0

누구에게나 적용 되는가? 나는 그것을 작동시킬 수 없었다. –

+0

그것은 나를 위해 작동합니다. = D 귀하의 잘못은 무엇입니까? – Aaron

+0

@Aaron : Watch 윈도우에 $ TID를 입력하면 VS 2008을 사용하고 있습니다. "이름이 curren 컨텍스트에 존재하지 않습니다." – akif

21

때문에 찾고 있어요 대답하지 않습니다 스레드 디버그 창 (Ctrl + Alt + gh)을 사용하여 다른 스레드를 멈추거나 다른 스레드로 전환 할 수 있습니다.

+0

감사합니다. 이것은 지금까지 본 적이있는이 좋은 해결책에 가장 가깝습니다! – Laserallan

+4

그게 내가하고있는 일이야, 질문은 ... 왜 단일 단계가 스레드가 실행되는 것을 바꿀까요? –

6

간단한 방법은 스레드 창에서 다른 모든 스레드를 동결하는 것입니다.

+3

VS 전환 스레드를 만들 수있는 방법이 없습니까? 어떤 상황에서 디버거가 라인을 넘어서서 다음 스레드에 도착할 때 다른 스레드로 전환하는 것은 의미가 있습니까? – stu

+0

아무에게도이 매크로가 있습니까?플러그인이나 매크로가 다른 모든 스레드를 정지시키고 다른 모든 스레드를 고정 해제 한 다음 스틴 인/오버를 수행하는 것이 좋습니다. 그것이 내가하는 일을 효과적으로하는 것입니다. 자동화하는 방법이 있어야합니다. – stu

+0

물론 비주얼 스튜디오에서 제대로 작동해야합니다. – stu

2

[CTRL + D, T] 또는 [Ctrl + Alt + H는] -

스레드 창을 표시하려는 경우 선택할 수 있습니다 (모니터 동결 및 이름 스레드가하는 데 사용) 스레드 창을 엽니 다 비주얼 스튜디오에서 다른 스레드의 위치. 디버깅 할 현재 스레드가 유일한 스레드가 아니라는 것을 나에게 알리는 좋은 알림입니다. 스레드 표식 위로 마우스를 가져 가면 스레드 이름과 ID가 표시됩니다.당신이 F10을 누르면 디버거 전이나 타격을받을 것이다 브레이크 포인트가 설정되어있는 경우 해당 스레드에 침입했을 때 http://devpinoy.org/blogs/jakelite/archive/2009/01/10/5-tips-on-debugging-multi-threaded-code-in-visual-studio-net.aspx

2

분명히, 비주얼 스튜디오 2010은 다른 스레드로 전환 :

더 많은 정보는에서 찾을 이 스레드에서. 당신이 프로그램에 또는 Main() 방법에 중단 점을 추가 단지 stept 메인 스레드에서 코드를 통해 F10에만 단계를 치는 경우

class Program 
{ 
    static void Main(string[] args) 
    { 
     var t = new Thread(new ThreadStart(Work)); 
     t.Start(); 

     for (int i = 0; i < 20; i++) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine("............"); 
     } 

     t.Join(); 
    } 

    static void Work() 
    { 
     for (int i = 0; i < 20; i++) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine("ZZzzzzzzzzzzzzzz"); 
     } 
    } 
} 

:

나는 동작을 테스트하려면 다음 코드를 사용 .

Work() 메서드에 중단 점을 추가하면 디버거가 두 스레드를 단계별로 실행합니다.

의 Visual Studio이 동작은 의미가 있지만, 모두가 나에게 문서화되지 않은 기능 것 같아 ...

1

는 최근 단지 특정 스레드를 디버깅 같은 문제가 있었다. 위의 답변을 매우 포괄적이고 가치있는 것으로 (그리고 2 일 전에 찾았 으면 좋았을 때) 할인하지는 않겠지 만 다음과 같이 구현하여 "일상적인"문제 해결을 도왔습니다.

이 아이디어는 응용 프로그램에서 항상 수행하는 여러 스레드에서 동일한 클래스의 여러 인스턴스를 실행할 때의 간단한 해결 방법 일뿐입니다.

모든 클래스 인스턴스를 고유 한 ID 또는 이름으로 초기화하므로 인스턴스 작성 방법 또는 이유를 알 수 있습니다. - 그럼, 우리가 필요로 할 때 특정 인스턴스 (즉 스레드)를 디버깅하고 다른 스레드를 동결하지, 우리는 다음과 같은 추가 : 우리의 경우

if (instance.ID == myID) 
{ 
    // Assert BreakPoint 
} 

, 우리는 고정 된 ID의의를 구축, 그래서 우리는 우리가 원하는 ID를 알고 문제가있을 때 문제를 해결하십시오.

관련 문제