2009-08-14 2 views
4

내 Win32 콘솔 applicaton은 타사 라이브러리를 사용합니다. WinMain 전역 개체를 종료 한 후 파괴가 시작되고 AV가 어딘가 깊은 곳에서 발생합니다. 나는 정말로 쓰기 만하고 싶어한다.TerminateProcess를 사용할 때의 위험은 무엇입니까?

TerminateProcess(GetCurrentProcess(), 0); 

어딘가에 WinMain이있다. 이 작업을 수행하면 신청서가 정상적으로 종료됩니다.

MSDN says 이렇게하면 은 동적 연결 라이브러리 (DLL)에 의해 유지 관리되는 전역 데이터의 상태가 손상 될 수 있습니다. 나는 전역 객체를 가지고 있다면 그것의 소멸자가 실행되지 않고 데이터베이스 연결이나 비슷한 것을 완료하지 못할 수도 있음을 이해한다. 내 프로그램에는 그런 것이 없다.

TerminateProcess를 사용할 때의 위험은 무엇입니까? 내 목적을 위해 사용할 수 있는지 어떻게 결정합니까?

+0

"AV"란 무엇입니까? –

+1

AV = 액세스 위반, 잘못된 메모리 액세스로 인한 충돌 – Michael

+0

해당 타사 라이브러리의 특성은 어느 것입니까? –

답변

5

일반적으로 나쁜 것은 프로세스 외부의 개체와 상호 작용할 때 발생합니다. 예를 들어, 프로세스가 쓰고 다른 프로세스가 읽고 쓰는 여러 프로세스에서 사용하는 공유 메모리가 있습니다. 일반적으로 읽기와 쓰기를 동기화하기 위해 뮤텍스가 사용됩니다. 프로세스의 스레드가 뮤텍스를 획득하고 TerminatePorcess가 호출 될 때 변경 중에 중간에 뮤텍스가 포기되고 공유 메모리가 잠재적으로 일관성없는 상태로 남을 수 있습니다.

제 3 자 라이브러리 중 하나를 사용하지 못한 것으로 의심됩니다. DllMain은 다소 제한적이므로 라이브러리는 호출해야하는 함수를 초기화하고 초기화하지 않을 수 있습니다.

+1

문제를 일으킬 수있는 좋은 예를 선택했습니다. 이 문제를 디버깅 한 후, 라이브러리가 항상 언로드하기 전에 적절한 초기화 해제를 수행하는 콜백 함수를 호출하지 못하는 것이 문제라는 것을 알게되었습니다. 초기화되지 않으면 정적 전역 개체가 파괴되어 개체 풀이있는 힙이 먼저 파괴 된 다음 해당 개체를 할당 해제하려고합니다. 개체 포인터가 이미 할당되지 않은 힙 메모리를 가리키고 있기 때문에 충돌이 발생했습니다. – sharptooth

+0

응용 프로그램 종료 중에 항상 호출되었던 코드가 있으므로 해당 콜백에 의해 수행 된 것과 동일한 단계를 추가했습니다. 그리고 문제는 사라졌습니다. – sharptooth

+0

다행히 문제가 해결되었다고 들었습니다. –

6

ExtiProcess와 ExtiProcess의 문서에 따르면 DLL_PROCESS_DETACH 플래그가있는 DllMain을 호출하지 않고 DLL이 언로드된다는 것이 가장 큰 문제인 것으로 보입니다.

내 2cents : DllMain + DLL_PROCESS_DETACH에서 실행되는 몇 가지 중요한 작업이 혼란 스럽다는 문서가 편집증 상태입니다. 임계 상태를 유지하는 데 의존하는 사람은 이미 작업 관리자의 자비를 받고 있으므로이 API를 사용할 때 큰 위험은 없습니다.

+0

+1,하지만 다른 방법으로 반올림 해 보겠습니다 : TerminateProcess()를 사용하는 것은 작업 관리자를 통해 프로세스를 죽이는 것과 마찬가지로 위험합니다. –

4

"글로벌 데이터"를 해석하는 방법에 따라 다릅니다. 프로세스의 주소 공간에 저장된 데이터를 (보통대로) 가져 오면 조언은 이해가되지 않습니다. 메모리가 사라질 것이라는 것을 알고 있으므로 누가 그 일을 처리합니까?

그렇다면 DLL이 수행했을 수도있는 OS 전반의 내용을 언급하는 것일 수 있습니다. 이는 모든 프로세스의 수명이 다할 때까지 지속됩니다. 간단한 예제는 정리해야 할 수도있는 임시 파일입니다. 프로세스를 너무 많이 충돌 시키면 디스크 공간이 부족해질 수 있으므로 버릇을 만들지 않는 것이 가장 좋습니다.

6

AFAIK, "환상적"(COM 객체를 사용하여 스레드, 잠금, DB 연결 생성하기를 포함하되 이에 국한되지 않음)을 수행하지 않는다면 아무런 일도 일어나지 않을 것입니다. 그러나 Earwicker says으로 을 알지 못합니다. DLL이 어떤 OS 전반의 항목인지, 그리고 앞으로 변경 될지 확실하지 않으므로 매우 의존적입니다.

왜이 액세스 위반이 발생하는지 알고 싶지 않습니까? 훨씬 이전에 손상된 무언가의 표시 일 수 있습니다. 이상으로을 확인하십시오. 버그는이 타사 라이브러리 (예 : 라이브러리와 링크하지만 아무런 동작도하지 않는 프로그램을 작성하여 동일한 크래시가 발생하는지 확인합니다.

+0

빈 main()이있는 좋은 아이디어 –

관련 문제