2011-04-11 5 views
2

디버그 환경에서 지금까지 재현 할 수없는 클라이언트 크래시를 진단하려고합니다.CallbackOnCollectedDelegate - 디버거가 연결되지 않은 경우 어떻게됩니까?

CallbackOnCollectedDelegate 디버거가 연결되지 않은 경우 MDA 알림 (제 3 자 코드의 결과)이 그렇지 않으면 크래시가 발생했는지 여부를 확인하려고합니다.

그래서 문제는 수집 된 대리인에 대한 콜백을 야기하는 타사 코드의 문제가이 동작의 원인이 될 수 있습니까? 디버깅 할 때 MDA, 그렇지 않을 때 클라이언트 크래시가 발생합니까? 이 MDA에

정보 : 문제를 다음 확실히 생식 - 에드 그 MDA 경고를 받았다면 http://msdn.microsoft.com/en-us/library/43yky316(v=vs.80).aspx

답변

3

. 예, 디버거가 없으면 하드 충돌이 발생합니다. 콜백을하면 기본 코드가 폭탄이됩니다. 네이티브에서 관리 코드로 호출을 정렬하는 스텁은 더 이상 존재하지 않습니다. 스텁을 수집 한 후 메모리 위치가 다시 사용될 때 메모리 위치가 유효한 주소를 참조 할 수 있기 때문에 AVE에 대한 가능성은 100 % 보장되지는 않지만 높습니다. 무작위 코드 실행은 실패 모드입니다. 결과는 지나치게 추악하고 진단하기가 어렵습니다.

네이티브 코드에 전달한 대리자에 대한 참조를 저장하지 않아서 발생합니다. 또는 레퍼런스를 저장하는 객체를 그대로 유지하는 것은 똑같은 일입니다. 가비지 컬렉터는 네이티브 코드가 스텁을 사용하고 있는지 알지 못합니다. 실제로 CLR은 대리자가 수집 될 때 스텁을 파괴합니다. 즉, 스텁의 메모리 할당을 관리하는 방법입니다.

이런 일이 발생하지 않도록하는 것은 사용자의 책임입니다. 대개 올바른 해결책은 대리자 개체 참조를 전용 static 변수에 저장하는 것입니다. 명시 적으로 네이티브 코드가 더 이상 콜백을하지 않는다고 명시했을 때만 null으로 다시 설정하십시오. null로 다시 설정하지 않는 것은 아주 일반적입니다. 또한 변수를 할당하기 전에 null인지 확인하기위한 테스트를 추가하고 그렇지 않은 경우 InvalidOperationException을 throw하십시오. 추가 수준의 간접 지정이 필요하면 GCHandle.Alloc(Object)을 사용하십시오. 같은 제조법, 당신이 그것이 안전하다는 것을 알기 전까지는 Free()를 부르지 마십시오.

+0

네 번째 파티 (?) JBIG2 디코더에 대한 타사 .NET 래퍼에 문제가 발생했습니다. 나는 벤더가 같은 코드에서 액세스 위반을 고치기 위해 1 년을 기다렸다. : –

+0

또한이 코드 주위에 catch (AccessViolationException)가 있습니다. 이론적으로 MDA에서는 액세스 위반이 발생한다고 말합니다. AVE를 throw하지 않는 이유는 무엇입니까? –

+0

이 코드는 네이티브 코드가 당신은 관리되는 코드로 그것을 잡을 수 없다. –

관련 문제