2008-10-08 14 views
5

프로그램을 닫은 후에 만 ​​예외가 발생하는 것으로 보이는 응용 프로그램이 있습니다. 그리고 그것은 매우 일치하지 않습니다. (우리 모두는 일관성없는 버그가 얼마나 재미 있는지 알고 있습니다 ...)예외 발생 (오류 발생) 프로그램 종료 후

정리 프로세스 중에 오류가 발생했습니다. 그러나 이러한 메모리 읽기/쓰기 오류는 "안전하지 않은"코드 사용 (포인터?)에서 잘못된 점을 나타내는 것 같습니다.

내가 관심을 갖는 것은 이러한 상황을 디버깅하는 가장 좋은 방법은 무엇입니까?
이미 닫힌 프로그램을 어떻게 디버깅합니까?
큰 문제를 해결하기위한 출발점을 찾고 있습니다.

이러한 오류는 여러 가지 방법 (일부 실행 시간, 일부 디버그) 자신을 제시하는 것 :

 
1: .NET-BroadcastEventWindow.2.0.0.0.378734a.0: Application.exe - Application Error
The instruction at "0x03b4eddb" referenced memory at "0x00000004". The memory could not be "written". 2: Application.vshost.exe - Application Error
The instruction at "0x0450eddb" referenced memory at "0x00000004". The memory could not be "written". 3: Application.vshost.exe - Application Error
The instruction at "0x7c911669" referenced memory at "0x00000000". The memory could not be "read". 4: Application.vshost.exe - Application Error
The instruction at "0x7c910ed4" referenced memory at "0xfffffff8". The memory could not be "read".

답변

4

응용 프로그램이 멀티 스레드 인 경우 제대로 종료되지 않고 처리 된 객체에 액세스하려고하는 작업자 스레드에서 오류가 발생할 수 있습니다.

+0

예 멀티 스레드입니다. 개발자는 대용량 스레드 수를 줄이는 경향이 있지만 내 애플리케이션에는 여러 애니메이션 그래픽이 동시에 실행될 수 있으므로 중요한 스레드 수가 계산됩니다. – PersistenceOfVision

+0

멀티 스레드는 자체적 인 죄악이 아니지만 프로세스가 종료 된 후에 오랫동안 잘못된 스레드 (또는 2 개)가 충전되어있을 가능성이 큽니다. 앱을 종료 한 후 프로세스가 실행 중인지 확인하십시오. –

+0

@ [PersistenceOfVision] : 보조 스레드가 범인이라고 의심되면 SafeThreads로 대체하려고 할 수 있습니다. http://www.codeproject.com/KB/threads/SafeThread.aspx –

1

내가 최근 다만이 같은 plently 오류 보았다. 내 문제는 .NET 런타임과 상호 작용하는 CRT (C 런타임)가 닫는 프로세스를 정리하는 방법과 관련이 있습니다. 내 응용 프로그램은 사실 C++이기 때문에 복잡해졌지만 COM 추가 기능을로드 할 수 있습니다. 일부는 C#으로 작성되었습니다.

이것을 디버깅하려면 기본 디버깅을 사용해야 할 것입니다. Visual Studio (혼합 모드 디버깅으로 설정) 또는 WinDbg. Microsoft 공용 기호 서버를 사용하여 Windows 구성 요소 용 PDB를 다운로드하는 방법을 찾으십시오. 기호가 필요합니다.

많은 문제가 .NET의 (끔찍한) COM 클라이언트 지원 문제였습니다. 나는 그것이 정확하게 (개발자의 말에 많은 작업을하지 않고) 참조를 참조하지 않기 때문에 끔찍한 말을한다. COM 개체는 가비지 수집이 완료 될 때까지 0으로 카운트 다운되지 않았습니다. 이것은 종종 셧다운 중에 이상한 타이밍 문제를 일으킨다. COM 객체는 오랜 시간 동안 정리되어야한다.

1

"일치하지 않는"단어는 "비 결정적"입니다. 그리고 .NET 환경에서 비 결정적으로 발생하는 상황은 무엇입니까? 개체 파괴.

내게 이런 일이 일어 났을 때, 안전하지 않은 호출을 외부 API에 랩핑하려고 쓴 클래스에 범인이있었습니다. 클래스의 소멸자에 정리 코드를 넣고 객체가 범위를 벗어 났을 때 코드를 호출 할 것으로 예상합니다. 하지만 .NET에서 오브젝트 파괴가 작동하는 방식이 아닙니다. 오브젝트가 범위를 벗어나면 파이널 라이저의 큐에 저장되고 소멸자는 파이널 라이저가 호출 될 때까지 호출되지 않습니다. 프로그램이 종료 될 때까지이 작업을 수행하지 못할 수도 있습니다. 이런 일이 발생하면 결과는 여기서 설명하는 것과 매우 비슷하게 보입니다.

일단 클래스를 구현하여 IDisposable을 구현하고 개체를 완료했을 때 명시 적으로 Dispose()이라고하면 문제가 사라졌습니다. IDisposable을 구현하는 또 다른 이점은 using 블록의 시작 부분에서 개체를 인스턴스화하고 코드가 블록을 벗어날 때 Dispose()가 얻을 수 있다고 확신 할 수 있다는 것입니다.)

0

는 프로그램 제어

//set as many statics as you can to null; 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
} //exit main 
0

에서 오류가 제안 된 코드를 사용하여 이후에 나타나는 중지하는 동안이 일이 버그를 억지로 :

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
6

내가 AcrobarReader COM 구성 요소를 사용하여이 문제를 가지고 있었다. 때마다 응용 프로그램 종료 후 "Application.vshost.exe - 응용 프로그램 오류" "메모리를 읽을 수 없습니다". GC.Collect() 및 WaitForPendingFinalizers()가 도움이되지 않았습니다.

내 google-fu이 페이지로 이동 : http://support.microsoft.com/kb/826220. 내 경우에 대해 방법 3을 수정했습니다.

프로세스 탐색기를 사용하면 AcroPDF.dll이 주 기능의 마지막 줄 전에 릴리스되지 않은 것으로 나타났습니다. API 호출이 왔습니다.

DLLImports (같이 DllImport는 System.Runtime.InteropServices 네임 스페이스에) :

<DllImport("kernel32.dll", EntryPoint:="GetModuleHandle", _ 
     SetLastError:=True, CharSet:=CharSet.Auto, _ 
     CallingConvention:=CallingConvention.StdCall)> _ 
Public Overloads Shared Function GetModuleHandle(ByVal sLibName As String) As IntPtr 
End Function 

<DllImport("kernel32.dll", EntryPoint:="FreeLibrary", _ 
    SetLastError:=True, CallingConvention:=CallingConvention.StdCall)> _ 
Public Overloads Shared Function FreeLibrary(ByVal hMod As IntPtr) As Integer 
End Function 

그리고 응용 프로그램 종료 전에 :

Dim hOwcHandle As IntPtr = GetModuleHandle("AcroPDF.dll") 
If Not hOwcHandle.Equals(IntPtr.Zero) Then 
    FreeLibrary(hOwcHandle) 
    Debug.WriteLine("AcroPDF.dll freed") 
End If 

이 절차는 어떤 부당한 행동 dll을 수정할 수 있습니다. 새 버그를 추가하지 않기를 바랍니다.

+0

이것은 나를 위해 일했습니다! 일부 VB6 DLL은 System.Environment.Exit() 호출 전에 해제되지 않았습니다. – JRS

+0

위대한 솔루션, 나를 위해 일했다. 감사합니다 – ahoo

+0

정말 고마워요! GetModuleHandle 및 FreeLibrary 메서드를 사용하면 릴리즈되지 않은 관리되지 않는 리소스를 정리할 수있었습니다. – Frinavale