2008-10-14 4 views
4

문제가 있습니다. 개발중인 응용 프로그램 사용자 중 한 명이 가끔은 있지만 정기적으로 응용 프로그램이 멈추는 현상이 발생합니다.프로덕션 .Net 데스크톱 프로그램에서 진단 응용 프로그램이 응답

이 경우 시스템의 이벤트 로그에 "Application hang [my app], 버전 [올바른 버전], hang 모듈 hungapp, version"이라는 유익한 메시지가있는 "Application Hang"소스가있는 항목이 있습니다 0.0.0.0, 행 주소 0x00000000. "

내 응용 프로그램이 처리하지 않은 모든 처리되지 않은 예외를 로깅하고 있으며 이런 일이 발생하면 내 로그 파일에 항목이 없습니다.

내 현재 작동 가설은 응용 프로그램이 안전하지 않은 기존 API를 호출하는 중에이 중단이 발생하고 있다는 것입니다. 이것은 나를 놀라게하지 않을 것이다; 수년 동안이 API를 사용하여 작업 해 왔지만 이전에는 멈추지 않았지만 진정으로 진절머리 나는 코드입니다. 또한 사용자가 프로그램이 임의의 시간에 응답하지 않는 것으로보고합니다. 나는 이것이 사실이라고 생각하지 않는다. 아니, 나는 그녀를 믿을 수는 없지만, 레거시 API와 통신하는 코드는 BackgroundWorker에 의해 호출되는 메서드 내에서 실행 중이다. 백그라운드 스레드가 응용 프로그램을 멈추게 만들었다면 사용자에게 무작위로 발생하는 것처럼 보일 수 있습니다.

두 가지 질문이 있습니다. 하나는 구체적이고 하나는 일반입니다.

특정 질문 : 비 UI 스레드에서 실행되는 메서드가 멈추는 경우 스레드를 죽일 것으로 예상됩니다. 실제로 전체 응용 프로그램을 죽일 것입니까?

일반적인 질문 :

처리되지 않은 모든 예외를 이미 로깅하고 있습니다. 내 프로그램은 이미 추적을 사용하도록 설정되어 있습니다 (의심스러운 메소드의 활동을 추적하기 위해 계측 코드를 추가해야 할 필요가 있습니다). 내가해야 할 다른 일이 있습니까? .NET 응용 프로그램이 중단 될 때 일종의 사후 충돌 분석을 허용하는 진단 도구가 있습니까? .NET 프레임 워크 내부에 더 많은 (더 유용한) 데이터를 캡처 할 수있는 메커니즘이 있습니까?

편집 : 내 코드를 자세히 살펴보면 BackgroundWorker의 모든 사용법은 예외 처리기에서 호출 된 메서드를 래핑하는 유틸리티 클래스를 통해 수행된다는 것을 기억하고 있습니다. 이 처리기는 예외를 기록한 다음이를 유틸리티 개체의 프로 포 셔널로 반환합니다. UI 스레드의 완료 이벤트 처리기는 예외를 다시 throw하지만 (호출 스택을 잃어 버리기 때문에 이상적이지는 않지만 이미 기록되어 있습니다) UI의 주 예외 처리기가 예외를 메시지 상자에보고 한 다음 종료합니다. 앱.

아무 것도 일어나지 않기 때문에 배경 스레드에 예외가 발생하지 않는다고 확신합니다. 어쨌든 .NET 예외는 없습니다.

또한 후속은 : 사용자의

자비 롭게, 지금 왔 충분한 ​​데이터는 요령은 기존의 API 내부에서 발생되지 않는다는 것을 확신 할 수 있습니다. 이것은 분명히 내가 잘못하고있는 것을 의미합니다. 즉, 고칠 수 있기 때문에이기십시오. 또한 추적을 통해 문제를 격리 할 수 ​​있음을 의미합니다. 이는 또 다른 이점입니다. 나는이 질문에 대한 답에 매우 행복하다. 나는 "아마이 문제에 대한 그들을 필요가 없습니다 심지어 행복 해요 또한

:.. PostSharp 뛰어난 당신이 기존 응용 프로그램에 계측 코드를 추가해야하는 경우는 거의 확실하게 그것을 사용해야

답변

0
.

생각 1) step into.(내 직장에서 KB에서) 순 프레임 워크 코드 :

  1. 의 선택을 해제 내 코드 만 사용 디버깅> - -> 옵션

    당신이 VS2008 SP1을 설치 한 경우

    , 당신이해야 할 모든 도구로 이동입니다 .NET 프레임 워크 소스는

  2. 확인이 디버깅에서
  3. 소스 서버 지원 사용 스테핑 사용
  4. 확인 -> 기호의 새 위치를 추가 http://referencesource.microsoft.com/symbols

호출 스택에서 회색조 프레임 워크 코드를 디버깅 할 때 호출 라인을 마우스 오른쪽 버튼으로 클릭하고 심볼로드를 선택하십시오.

사상 2) 설정 원격 디버깅 배경/작업자 스레드 블록 또는 중단, 응용 프로그램의 나머지 부분에 미치는 영향이 사이에 일어나는 동기화에 많이 달려 http://msdn.microsoft.com/en-us/library/y7f5zaaa.aspx 특정 질문에 대한 대답에서

+0

원격 디버깅이 필요할 수 있습니다. 일종의 원격 컴퓨터에서 디버깅을 사용하려면 VS DVD를 사용해야한다는 점에 놀랐습니다. 원격 기계의 주요 특징은 무엇입니까? 그것은 * 원격 *입니다. 약 80 마일 정도 떨어진 곳이야. –

4

, 응용 프로그램의 스레드. 앱이 반드시 전체 앱에 걸려 들게하는 특별한 이유는 없습니다.하지만 전적으로 가능할 수 있습니다.

이 문제를 진단하는 한 가지 가능한 방법은 멈춰있는 동안 프로세스 덤프를 생성하는 것입니다 (누군가가 일어날 때 주위를 알아 차리고 있다고 가정 할 때). 이 작업은 dbghelp.dll의 MiniDumpWriteDump을 사용하여 수행됩니다. 문제를 겪고있는 고객에게 제공 될 수있는 프로세스를 덤프 할 수있는 간단한 도구를 작성하는 것은 매우 간단합니다. 이것은 관리되는 응용 프로그램이므로 전체 메모리 덤프 (MiniDumpWithFullMemory)가 바람직하지만 정상 덤프에는 여전히 유용한 정보가 있어야합니다. 일단 덤프가 있으면 windbg 나 사후 디버거를 사용하여 무슨 일이 벌어지는 지 확인할 수 있습니다.

이 경로를 사용하면 this msdn article은 관리되는 덤프 디버깅을위한 좋은 출발점입니다.

1

문제의 원인이라고 생각되는 전화를 통해 자세한 로깅을 추가하는 것이 좋습니다.

비스타를 사용하는 경우 새로운 Vista API를 사용하면 응용 프로그램이 충돌 할 때 Windows에서 코드를 호출 할 수 있습니다. Office/IE와 같은 MS 제품이 "데이터 복구를 시도 중"이라고 말하면서 이런 일이 발생합니다.

+0

필자는 의심되는 방법에 이미 계측 코드를 추가 할 예정입니다. 저는 비스타를 사용하는 동안이 사용자는 XP에 있습니다. –

0

제어하는 ​​스레드에 처리되지 않은 실행이있는 경우 it will bring down your entire application. 스레드가 죽으면 "처리"할 방법이 없습니다. APM with delegates을 어떻게 사용할 수 있는지 살펴볼 수 있습니다. EndInvoke()를 호출 할 때 예외가 캡처되고 전달되므로 다른 스레드에서 throw 된 예외로부터 보호 계층을 제공합니다.

내가 할 수있는 다른 방법은 다음과 같습니다. Charlie's 답변.

0

가능한 경우 배경 작업자 스레드를 SafeThread으로 바꾸고 의심되는 예외를 catch하는지 확인하십시오. 그렇지 않으면 예외가 throw 된 CLR 예외가 아니므로 '순수'.NET 코드에서 처리 할 수 ​​없습니다. [SEH C++에서 작동 할 수도 있습니다]

EDIT : 그렇지 않습니다. 아마도 this 또는 this 일 수 있습니다. 행운을 빕니다!

+0

제 편집에서 언급했듯이, 저는 SafeThread와 거의 동일한 것을 이미 사용하고 있습니다. 그리고 지금 일어나고있는 일이 CLR 예외가 아니라는 것을 확신합니다. –

+0

@ [Robert Rossney] : 음 ... 아무런 단서가 없습니다. 새 링크에 대한 내 수정 사항을 확인하십시오. 행운을 빕니다! –

0

로버트, 이러한 모든 해결책이 실패하고 여전히 기존 API가 범인이라고 생각하는 경우 레거시 API를 자체 AppDomain 또는 프로세스에 샌드위치 처리하는 것이 해결책 일 수 있습니다.

.NET 3.5 프레임 워크는 System.AddIn API를 사용하여 매우 쉽게 만듭니다.

0

WinDbg (예, 해당 하드 코어 중 하나)를 연결하고 SOS (Son of Strike) 및 SOSEx를 사용하여 교착 상태 (! dlk)를 분석하거나 수동으로 동기화 블록 (! syncblk)을 확인하여 상호 대기 잠금 .

관련 문제