2009-08-01 2 views
3

내 소프트웨어를 사용하는 클라이언트 중 하나와 막 다른 상황이 있습니다. VB.NET 2005를 사용하여 .NET 2.0에서 프로그래밍 된 약 40 개의 제품 중 약 2 개의 제품이 100 %로 고정 된 듀얼 코어 CPU의 1 코어에서 응답하지 않음 (프로그램에서 1 코어 만 사용)CPU가 고객 PC에서 100 % 멈췄다면 디버깅 제안 사항이 있습니까?

가장 논리적 인 추측은이 동작을 일으키는 무한 루프이지만 많은 수의 루프가있는 수천 줄의 코드 줄입니다. 그게 내가 가진 모든 정보입니다. 지금,이 문제를 디버깅하는 방법에 대해 어떻게 제안합니까?

편집 : 기본적으로 소프트웨어는 PC와 같은 다른 장치를 사용하여 지출 한 크레딧 금액을 계산합니다. Cybercafe 관리 프로그램이며 일시적으로 실패합니다. 즉, 실패하면 신용을 빼는 것입니다. 다른 것들도 배경으로, 데이터베이스 백업을 생성 할 시간인지 확인하는 것과 같은 다른 작업도 수행합니다.

편집 : 해결. 가장 드문 문제였습니다. DBMS로 사용 된 Access 데이터베이스 엔진은 실제로 문제가되는 내 응용 프로그램의 일부입니다. 테이블 중 하나에서 행 하나만을 처리하는 데 어려움이 있습니다. 삭제할 수 없거나 다른 행에 관련된 레코드를 다른 테이블에 추가 할 수 없습니다. MS Access 2007조차도 그 행을 사용하려고 할 때 CPU가 최대 100 %가됩니다!

단순한 "압축 및 복구"명령은 모든 것을 수정했습니다. 응용 프로그램이 시작될 때마다 해당 명령을 실행하겠습니다. 그러면 다시 발생하지 않을 것입니다.

WinDbg 덕분에 문제가있는 부분을 찾을 수있었습니다. 나는 그것을 사용하는 방법을 배우는 것이 좋습니다. 왜냐하면 그것은 실시간 세이버이기 때문입니다.

+0

Jet/ACE 백 엔드를 사용하여 제품을 판매하고 있으며 데이터 저장소의 일상적인 유지 관리의 중요성에 대해 알지 못했습니까? 귀하의 고객은 무능함을 이유로 귀하를 고소해야합니다. –

+0

Microsoft의 사람들이 "이봐, 데이터베이스가 손상 될 것 같아서 Access에서 메뉴 명령을 사용하여 고쳐야 해!"라고 생각하지 않았습니다. 그들은 SQL Server를 사용하는 사람들에게 똑같은 말을 할 것입니까?! – TheAgent

+0

그것은 제트기 다. 그들은 그것을 말할 필요가 없다. ;) SQL Server의 주요 판매원 중 하나는 "Jet가 아닙니다."입니다. –

답변

7

설치 windbg를 (윈도우 디버거) 대상 컴퓨터에서 잘 작동하고있다. 디버거를 호출하고 의심스러운 프로세스에 연결하고 프로그램을 실행 한 다음 문제가 발생할 때까지 기다립니다. 문제가 발생하면, 이것은 당신의 스레드 중 어느 것이 대부분의 시간을 소모하는 표시됩니다

폭주 디버거 명령 행

에서 다음 명령을! 호출합니다. 그런 다음 대부분의 CPU 리소스를 소비하는 스레드에서 여러 스레드 스택을 가져옵니다.

0:015> !runaway 

사용자 모드 시간 스레드 시간 0 : 1,074 0 0 일 : 00 : 21.637 11 : 137C 0 0 일 : 00 : 02.792 4 : 12c8 0일 여기

은 일례이며 0 : 00 : 00.530 9 : 1,374 0 0 일 : 00 : 00.046 15 : 13d0 0 0 일 : 00 : 00.000 14 1,204 0 0 일 : 00 : 00.000 13 : 154C 0 0 일 : 00 : 00.000 12 : 144c 0 일 0 : 00 : 00.000 10 : 1378 0 일 0 : 00 : 00.000 8 : 1340 0 일 0 : 00 : 00.000 7 12f0 0 0 일 : 00 : 00.000 6 12d4 0 0 일 : 00 : 00.000 5 : 12d0 0 0 일 : 00 : 00.000 3 : 12c4 0 0 일 : 00 : 00.000 2 : 12c0 0 일 0 : 00 : 00.000 1 : 12b4 0 일 00 : 00.000

이제 우리는 목록 11의 두 번째 스레드에 대한 호출 스택을 원한다고 가정하므로 먼저 스레드 11 ~ 11 초를 입력하면됩니다.

0:015> ~11s 

EAX = 03fbb270 EBX = FFFFFFFF ECX ​​= 00000002 EDX = 00,000,060 ESI = 00000000 EDI = 00000000 EIP = 77475e74 ESP = 0572f60c EBP = 0572f67c IOPL = 0 NV 최대 EI PL ZR NA PE NC CS = 001B SS = 0023 DS = 0023 ES = 0023 FS = 003B GS = 0000 EFL = 00000246 의 ntdll KiFastSystemCallRet! 77475e74 C3의 RET

이제 KP 실행하여이 스레드에 대한 호출 스택을 얻을 :

0:011> kp 
ChildEBP RetAddr 
0572f608 77475620 ntdll!KiFastSystemCallRet 
0572f60c 75b09884 ntdll!NtWaitForSingleObject+0xc 
0572f67c 75b097f2 kernel32!WaitForSingleObjectEx+0xbe 
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Mozilla Firefox 3.1 Beta 1\nspr4.dll - 
0572f690 10019a0b kernel32!WaitForSingleObject+0x12 
WARNING: Stack unwind information not available. Following frames may be wrong. 
0572f6ac 10015979 nspr4!PR_MD_WAIT_CV+0x8b 
0572f6c4 10015763 nspr4!PR_GetPrimordialCPU+0x79 
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Mozilla Firefox 3.1 Beta 1\xul.dll - 
0572f6e0 64d44d6a nspr4!PR_Wait+0x33 
0572f708 64dbe67e xul!NS_CycleCollectorForget2_P+0x698a 
0572f72c 10019b3f xul!gfxWindowsPlatform::FontEnumProc+0xfd4e 
0572f734 10015d32 nspr4!PR_MD_UNLOCK+0x1f 
0572f738 1001624b nspr4!PR_Unlock+0x22 
0572f754 1001838d nspr4!PRP_TryLock+0x4cb 
00000000 00000000 nspr4!PR_Now+0x109d 

을 공동 mmand kp가 매개 변수를 인쇄합니다. 로컬 변수는 dv로 인쇄 할 수 있습니다.

또는 sysinternals의 프로세스 탐색기를 사용할 수 있습니다.

원격 클라이언트 시스템이므로이 모든 작업을 수행 할 수없는 경우 추가 분석을 위해 사용자에게 보낼 수있는 덤프 파일을 만드는 userdump를 설치하십시오. 고객이 올바른 매개 변수로 userdump를 호출 할 수 있도록 배치 파일을 만들 수 있습니다. Userdump는 자신의 웹 페이지에서 다운로드 할 수있는 Microsoft의 도구입니다.

+0

숫자가 스레드의 식별자로 나타납니다. 어떤 스레드가 문제를 일으키는 지 어떻게 알 수 있습니까? 특정 스레드가 어떤 메소드를 실행하고 있는지 알 수있는 방법이 있습니까? – TheAgent

+0

이것은 매우 도움이되었습니다. 이제 필요한 것은 스택의 모든 메소드에 어떤 매개 변수가 전송되었는지 알 수있는 것입니다. 매개 변수 값을 얻으려면 어떻게해야합니까? – TheAgent

2

그럼 꽉 끼는 부분을 해결해야합니다. 당시 고객이 소프트웨어로 수행 한 작업은 무엇입니까? 처음부터 소프트웨어는 무엇을합니까?

코드에 많은 로깅을 추가하고 클라이언트에 모든 로깅을 사용하도록 설정하여 문제가 발생한 위치를 추적 할 수 있습니다.

4

가능한 경우 프로세스 덤프를 가져 와서 스택 추적을 확인하십시오.
나는 그것을 한 적이 없지만 VS/WinDbg 및 SOS (Strike의 아들)와 함께 작동해야합니다. 여기에 대해 blog post입니다.

2

과 같은 로거를 사용하면 postsharp으로 기존 코드베이스에 소개 할 수 있습니다. 모든 메소드 항목과 종료를 기록하십시오. 따라서 오류가있는 메소드를 찾아야합니다. 그래도 필요한 경우 로깅을 개선 할 수 있습니다.

경험이 없지만 vb.net에서도 작동하는 것처럼 보입니다. 어쩌면 this article가 도움이 될지도 모릅니다.

+0

아하. 포스트 샤프로 모든 것을 추적하면 트릭을 좁히고 특정 기능에 대한 좁은 결과를 얻을 수 있습니다. –

2

이러한 클라이언트와 매우 면밀하게 인터뷰해야합니다. 그게 항상 쉽지는 않지만 문제를 좁히는 유일한 기회입니다.

그런 다음주의 깊게 추적 기능을 추가하고 전략 포인트에서 플러시하거나 자동 플러시를 설정하는 것을 잊지 마십시오.

그러나 때문에 추적의 추가 지연으로 도망 간다 미묘한 타이밍 문제가 될 수 ...

1

예를 들어, 싱글 코어 및 멀티 코어 CPU 다르게 행동에 문제가있을 수 있습니다 백그라운드 스레드가 UI를 업데이트하려고합니다.

(배경과 UI 스레드를 분리하지 않고 멀티 코어 CPU가 주류를 띠게되는 어두운 시대에 앱을 작성했다는 것을 인정합니다.) 솔루션은 SetProcessAffinity를 호출하여 앱을 단일 코어)

그렇다면 100 % CPU가 특별한 종류의 CPU에서만 발생하는지 확인하고 SetProcessAffinity를 사용하여 문제가 해결되는지 확인해야합니다. 그렇다면 코드에서 어디에서 찾아야하는지 알 수 있습니다.

+0

무료 Process Explorer 유틸리티를 사용하여 실행중인 프로세스에 CPU 선호도를 설정할 수 있습니다. devio의 대답이 도움이되는지 확인하는 것으로 충분합니다. –

+0

알아, Windows TaskMgr도 할 수 있습니다. – TheAgent

4

무한 루프 인 경우 디버거를 연결하고 휴식을 시도하십시오. WinDbg이 이상적입니다.

이 기술은 루프가 너무 반복적이지만 코드의 나머지 부분과 함께 진행되는 경우에도 작동합니다. 좋은 샘플을 얻기 위해 절차를 반복하는 데 몇 분을 소비하는 것이 가능합니다.

이 기술은 나에게 여러 번 저장도 정지 된 응용 프로그램 :

+0

+1 우수 제안, Thomas. 오늘날 많은 개발자들이 WinDbg와 같은 응용 프로그램을 사용하지 않는 것처럼 보입니다. SOS는 CLR에 대한 정보도 제공해야합니다. OP 레퍼런스에 제공된 링크 : http://msdn.microsoft.com/en-us/library/bb190764.aspx –

+0

감사 : SOS에 대한 좋은 지적. .NET의 마법 선은 : '.loadby sos mscorwks' –

+0

WinDbg는 관리 코드 시스템이 아닙니다. C++ 코드를 본 경험이없는 대부분의 개발자는 그것이 존재한다는 것을 전혀 모릅니다. 나는 사용하지만 매일 사용하지 않기 때문에 사용하지 않아도됩니다. C#에서 windbg을 사용하려면 정말 흥미로운 코드를 작성해야합니다. – Spence

0

스레딩 문제 일 수 있습니까? "간헐적으로 실패"라고 생각하면 라고 생각합니다. 프로그램이 리모컨/DCOM/소켓과 같은 외부에서 신호/메시지 을 수신합니까? 해당 메시지와 관련된 정보가 사용자의 인터페이스에 표시됩니까?

나는 항상 개의 ASSERT를 사용하기 때문에 스레드 문제를 발견했습니다. 이 메시지의 이 될 XML-RPC를 통해 수신 시작을위한 정신 체크 ASSERT이었다

"<?xml " 

은과 ASSERT는 메시지의 메모리의 덮어 쓰기를 사로 잡았. 검사에 따르면이 부분은 중요 섹션의 누락 된 잠금 때문일 수 있습니다. 이 문제는 문제가 ASSERT에 의해 일찌기 잡혀 있었기 때문에 가능했습니다. (그리고 가 감지 될만큼 자주 발생했습니다).

이것은 매우 구체적이거나 지시 사항이 아니지만 일 수있는 위치에 ASSERT를 추가하는 것이 좋습니다.

ASSERT를 실행한다고해서 반드시 프로그램이 중단되거나 메시지 상자가 표시되는 것은 아닙니다. ASSERT는 ASSERT 실행시 전체 스택 추적을 포함하여 을 로그 파일로 리디렉션 할 수 있습니다.

관련 문제