2009-06-18 2 views
5

심각한 멀티 스레드 디버깅 문제가 있습니다. 직렬 장치와 상호 작용할 때 어떤 타이밍 문제가 있습니다.이를 추적해야합니다. 나는 세 개의 스레드가 있습니다 :C# 및 vs2008의 스레드 된 디버그

  1. UI 업데이트를위한 주요 스레드. 사용자는 사전 설정을 선택하여 장치의 한 매개 변수를 변경하거나 한 번에 여러 매개 변수를 변경할 수 있습니다.
  2. 장치가 여전히 연결되어 있는지 확인하기 위해 쿼리하는 상태 검사 스레드입니다. 사용자가 장치를 종료하거나 장치 자체가 흥미로운 방식으로 상호 작용할 경우 상태 변경 사항이 UI에 반영되어야합니다.
  3. 장치가 응답하는 직렬 포트를 읽는 스레드입니다.

제 문제는 실제로이 상황을 디버깅하는 것과 관련이 있습니다. 디버깅 할 때마다 각 스레드에서 하나의 줄마다 중단 점이 있어야하는 것처럼 보입니다. 하나의 스레드에서 중단되면 디버거는 해당 스레드를 단계별로 실행하지 않습니다. 다른 스레드가 계속해서 업데이트되지만, 디버거에서 정상적으로 실행되는 스레드가 없어야합니다. 즉 한 줄에서 다음 줄로 이동해야합니까? 그런 다음 'threads'탭을 사용하여 스레드간에 전환 할 수 있습니다.

내가 WPF에있는 이유는 그것이 상황을 전혀 바꾸지 못하기 때문이다. 어쩌면 그렇지 않을 수도 있습니다. 상태 검사 스레드는 UI가 작동하는 동안 만 상태를 확인해야하기 때문에 UI 컨트롤의 일부입니다. 이 컨트롤은 주 응용 프로그램과 별개의 라이브러리에 있습니다.

+0

WPF 참조가 제거 된 이유는 실제로 WPF와 관련이 없기 때문입니다. 일반적인 MT 디버깅입니다. –

+0

불행히도 vs2008이 프로젝트가 WPF로 마이그레이션 된 이후로 매우 극적으로 행동하기 시작했습니다 (이는 단지 하나의 문제 동작이고 다른 것은 소스 제어 및 다른 빌드 설정과 관련이 있습니다). 따라서 경우에 따라서 포함. – mmr

답변

1

코드가 이상한 방식으로 한 단계 씩 실행되는 경우 가끔은 간단한 pdb 파일로 인해 발생할 수 있습니다. 코드에서 "모두 다시 작성"하면 코드가 처음부터 다시 생성되어 이러한 결함을 치료할 수 있습니다.

또 다른 점은 디버거에서 하나의 스레드를 중지하면 릴리스 빌드에서 볼 수없는 모든 종류의 비정상적인 타이밍이 발생할 수 있다는 것입니다. 예를 들면 : 당신이 중단 점에서 중지 한 상태에서 직렬 포트는 항상 (하드웨어/드라이버 레벨에서) 계속 작동

  • - 당신이 다음 코드를 단계하려고 할 때, 그것은 갑자기 거대한 폭발을받을 수 있습니다 데이터의. 비동기 콜백을 사용하면 "재미있을"수 있습니다.

  • 스레드를 중지하면 정상적인 타임 슬레이핑이 방해되므로 스레드와 스레드의 동기화가 엉망이 될 수 있습니다.

7

디버거가 중단 점에서 중지되면 기본적으로 다른 모든 스레드가 일시 중단됩니다. 그러나 단계를 진행하거나 3 개의 스레드가 모두 재개됩니다. 코드를 단계별로 실행할 때 디버거는 기본적으로 다음 줄에 임시 중단 점을 설정하고 모든 스레드를 다시 시작합니다. 다른 2 개는 가상 브레이크 포인트가 충돌하기 전에 실행될 수 있습니다.

당신이 디버그를 선택 중단 점에있을 때

를 디버깅하는 동안 당신은 다른 스레드를 고정 할 수 있습니다 | Windows | 스레드. 관심이없는 스레드를 선택하고 마우스 오른쪽 단추를 클릭하고 Freeze을 선택하십시오. 이렇게하면 진행중인 한 스레드에 집중할 수 있습니다.

+0

하지만 요점은 임시 중단 점을 지정하지 않는다는 것입니다. 그것은 단지 blithely 계속 따라, 중단 점을 때리지 않고 원래 하나. 다른 스레드를 실행하고 싶습니다. 그들이 잘못 행동 한 곳을보고 싶습니다. – mmr

+0

스테핑 후에 수동으로 깨진 경우 어떻게됩니까? Win32 메서드에서 어딘가에 잃어 버렸습니까? 아니면 나중에 실제로 코드에서 멈추는 지요? –

+0

결코 멈추지 않고 그냥 계속 가고 있습니다. – mmr

1

나는 제이슨과있어, 스테핑은 더 이상 진리를 보여주지 않을 것이다.

Interlocked.Increment를 사용하여 카운터를 증가시키고 출력에 카운터를 추가하는 방법으로 코드의 각 줄을 계측하는 것이 좋습니다 (로컬 파일이 가장 좋습니다).

실제 이벤트의 순서가 항상 파일에 쓰는 순서와 같지 않기 때문에 카운터가 필요합니다. 스레드의 이름을 지정하거나 출력에 ID 값을 사용하십시오. MS Excel을 사용하여 파일을 열고 스레드에 따라 모든 행의 색상을 지정합니다.이 방법으로 인터리브 작업을 매우 명확하게 볼 수 있습니다.

각 잠금 장치가 켜지거나 꺼지는 동안 어떤 악기를 잠그는 래퍼 (wrapper)를 작성했습니다.

싱크로 문제는 t- 촬영에 끔찍한 것이므로 리팩터링에 소요되는 것보다 많은 것을 지출하지 말라고 조언합니다. 때때로 당신이 취하는 접근 방식이 차선책이라고 지적합니다.

필요한 경우 IO를 사용하여 휘발성 메모리를 사용해야합니다.