2010-01-14 3 views
2

델파이 2007에 응용 프로그램을 작성했습니다. 델파이 2007에서는 응용 프로그램이 24 시간 연중 무휴로 실행되는 경우가 있습니다. 주 스레드가 붙어있는 것처럼 보입니다. 이 문제의 원인을 찾아 낼 수있는 옵션은 무엇입니까?Delphi 응용 프로그램에서 메인 스레드 매달 기 디버그하는 방법

응용 프로그램은 Delphi 2007로 작성되었으며, RemObjects, DBExpress와 Firebird, COM을 사용한 OPC 통신을 사용합니다.

+0

코드에 대해 더 알지 못해도 말하기는 어렵습니다. CPU 및 메모리 사용이 중단 된 경우 (작업 관리자에서) 무엇입니까? 그것은 정적인가요? – fupsduck

+0

메모리 사용이 안정적이고 CPU 사용량이 0입니다. (실제로 상황을 조사 할 기회가 많지 않습니다.) – Harriv

답변

11

MadExcept를 사용하면 주 스레드가 메시지를 계속 처리하도록 정기적으로 검사하도록 지정할 수 있습니다 (긴 시간 제한보다 높은 값으로 설정). 주 스레드가 중단되면 스택 추적을 얻을 수 있습니다.

는 요령이 (아마도 예상 할 수있는) 드라이버에있을 때 나는 약간의 성공이 사용한 Main thread freeze checking...

, 그것은 단지 실패를 참조하십시오. 드라이버 (A/D 변환 카드 용)를 의심하기 시작한 후에 각 API 호출 전후에 추적 메시지를 추가하여 드라이버가 범인임을 증명할 수있었습니다. 신뢰할 수있는 로그 데이터를 얻으려면 파일에 즉시 메시지를 쓰고 버퍼를 플러시하는 것이 중요합니다.

또한 WinDbg을 사용하여 Delphi가 설치되지 않은 시스템에서 행글 실행 파일에 첨부 할 수있었습니다. 이것은 같은 순서로 항상 중요한 부분을 획득하는 것이 아니라 교착 상태로 판명되었습니다. WinDbg는 스레드 스택과 임계 섹션의 상태를 검사하여 이러한 상황을 분석하는 데 유용합니다.

+0

디스크의 순환 "이벤트 시퀀스"를 저장하기 위해 레코드 유형의 순환 버퍼를 사용합니다. 잠김 직전에 소프트웨어 상태를 확립하는 데 도움이 될 것입니다. 처리 할 가능성이있는 문제의 종류는 다음과 같습니다. 1. 교착 상태 : 교착 상태가 교착 상태가되는 방식으로 코드가 작성되었을뿐만 아니라 때문입니다. 코드의 중요한 섹션을 try..finally 블록으로 놓은 다음 중요한 섹션을 종료하지 않을 수도 있습니다. 2. 위의 드라이버 문제와 같은 API 호출이 멈 춥니 다. –

+0

워렌 P : 어떻게 이벤트 로깅을합니까? 어떤 종류의 이벤트를 기록합니까? – Harriv

+0

정보 주셔서 감사합니다! ** madExcept **를 통해 걸려있는 프로그램의 경우 위치는 'THandleObject.WaitFor (INFINITE)'입니다 :) –

4

메인 폼이 응답하는지 확인하는 "워치 독"스레드를 사용하고 미니 덤프를 만드십시오 (WinDbg로이 덤프를로드하고 map2dbg.exe를 사용하여 Delphi .map을 .dbg로 변환 할 수 있음) .

FMainformHandle := Application.MainForm.Handle; 
Result := SendMessageTimeOut(FMainformHandle, WM_NULL, 0, 0, 
     SMTO_NORMAL or SMTO_ABORTIFHUNG, 
     C_TIME_OUT_SECONDS * 1000, //wait 1minute 
     iRes) <> 0; 
if not Result then 
begin 
    hFile := CreateFile(PChar(Result), GENERIC_WRITE, FILE_SHARE_WRITE, nil, 
     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 
    try 
     MiniDumpWriteDump(GetCurrentProcess, GetCurrentProcessId, hFile, 
      aDumpType, nil, nil ,nil); 
    finally 
     FileClose(hfile); 
    end; 
end; 

그러나 당신은 또한

jclDebug.pas 사용할 수 있습니다
JclCreateThreadStackTraceFromID (MainthreadId)이 대한

(WinDbg는 등 만 JCL + 델파이에 대한 필요성을. 지도)

세 번째 옵션은 내 새 sampling profiler을 사용하는 것입니다.이 프로세스에는 "process s tack 뷰어 "이므로 실행중인 프로세스의 모든 스레드 스택을 볼 수 있습니다. 이전에는 SysInternals Process Explorer를 사용했지만 .dbg 파일이 필요합니다. 스택 추적을 위해 .map, TD32, JDBG 등 (모든 Delphi 디버그 정보)을 사용합니다.
앱을 중단 할 때 스택을 조사 할 때 사용할 수 있습니다. (MiniDumpWriteDump에 대한)

윈도우 API :
http://sourceforge.net/projects/jedi-apilib/files/JEDI%20Windows%20API/
WinDbg는 :
http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx
Map2Dbg :
http://code.google.com/p/map2dbg/
JEDI JCL :
http://jcl.delphi-jedi.org/
AsmProfiler, samling 모드 : (아직 개발중인!)
http://asmprofiler.googlecode.com/files/AsmSamplingProfiler0.4.zip

+0

샘플링 프로파일 러를 중단 된 응용 프로그램에 첨부 할 수 있습니까? 끊임없이 실행해야합니까? – Harriv

+0

당신은 실행중인 프로세스를 "볼"수 있습니다. 존재하는 한, 너무 매달린 응용 프로그램입니다 :-). Process Explorer로 매번 map2dbg를 변환하는 것에 지쳐서 프로파일 러에 약간의 추가 작업이 필요합니다 ... –

관련 문제