2009. 3. 3. 17:56
위의 제목을 보면 확 오지 않지만 지금부터의 내용은 application verifier를 사용해서 critical section의 사용에서 혹시 실수 할수 있는 부분에 대해 사전에 찾아 낼수 있는 팁을 적으려고 합니다.
아래의 간단한 예는 제가 3년정도 전에 서버 개발하면서 원인 모를 버그가 발생해 고생했던 부분인데 , 최근에 또 이렇게 작업된 소스를 보고 해결은 했지만 노파심에 간단하게 재현해 본것입니다.
( 아래 내용처럼 실제로 작업되어 있는것은 아니고 , 라이브러리를 사용하면서 이렇게 사용할수도 있는 것이기 때문에 , 예제를 만들어 본것입니다. 간단한 내용이지만 클래스가 라이브러리와 되어 많은 부분 속으로 파고 들어 있으면 쉽게 찾아 낼수 없는 부분입니다. ^^ )
일단 아래의 소스를 보지요.
#include <stdio.h>
#include <windows.h>
class clsTST
{
public:
CRITICAL_SECTION m_TestCS;
public:
clsTST();
~clsTST();
BOOL InitCS();
BOOL DelCS();
};
clsTST::clsTST()
{
InitCS();
}
clsTST::~clsTST()
{
DelCS();
}
BOOL clsTST::InitCS()
{
InitializeCriticalSection(&m_TestCS);
return TRUE;
}
BOOL clsTST::DelCS()
{
DeleteCriticalSection(&m_TestCS);
return true;
}
void NewDelClassTest()
{
clsTST * pTmp = NULL;
char * pPtr = NULL;
pTmp = new clsTST;
pPtr = (char*)pTmp;
//delete pTmp; // 1)
delete pPtr; // 2)
}
///////////////////////////////////////////////////////////////////////////////////////
// Func : main
// Author : 멋진넘
// Explain : 메인
///////////////////////////////////////////////////////////////////////////////////////
void main()
{
// delete에서 critical section을 남겨 두었을때 문제 상황 체크
NewDelClassTest();
printf("end ~ \n");
getchar();
}
critical section 개체는 InitializeCriticalSection() 한뒤에 꼭 DeleteCriticalSection()을 해줘야 합니다.
만약 하지 않으면 조금씩 리소스를 까먹고 한참 뒤에는 리소스 부족으로 서버를 다운 시키는 문제를 발생 시킬수도 있습니다.
더 큰문제는 Critical Section 구조체의 필드값들이 원하지 않게 변경되면서 정상적인 Lock, Unlock을 하지 못하는 문제가 생기는 경우도 있습니다.
위 소스에서 1) 처럼 삭제를 한다면 문제가 되지 않습니다. 하지만 2)의 경우 처럼 삭제를 한다면 소멸자가 불려지지 않기 때문에 지속적으로 문제가 발생하게 되지요.
하지만 일반적으로 VC에서는 2)번의 경우 오류를 발생시키지 않습니다. ( 사실 이것은 오류로 보기는 힘들죠 )
그러나 application verifier 을 설치하고 , 해당 exe파일을 등록시킨뒤에 디버그를 하면 criticla section을 삭제하지 않아서 , delete 시에 오류가 발생하는 것을 바로 볼 수 있습니다.
사전에 오류를 예방 할 수 있겠지요.
이러한 실수를 할 사람은 많을것 같지 않지만 , 여기서는 application verifier를 사용해서 사전에 미리 찾아낼수 있다는것에 포인트를 맞춰 주시기 바랍니다.
다만, 리얼환경에서 application verifier를 사용하지는 말아 주시기 바랍니다. 메모리 리소스 왕창 먹어 주시고요. CPU 많이 사용해 주십니다. 개발환경에서는 간간히 사용해 주시면 매우 좋겠지요.
댓글 없음:
댓글 쓰기