본문 바로가기
컴퓨터/디버깅

오랜 시행 후 프로그램이 멈추는 경우 - GDI 문제

by adnoctum 2013. 1. 1.




   다음과 같은 에러가 있다는 연락을 받았다.



1,2,3 trials을 한 번에 시행할 경우 중간에 멈추는 버그 발생


환경 : Visual Studio 2010 on Windows 7  Professional SP1, English, 64-bit. 




각 trial 은 대략 50~60개의 이미지를 보여주고 환자의 입력을 받는 것인데, 각 이미지 사이에 무반응자극 이미지를 한 장씩 보여 주게 되어 있다. 이런 상황에서 위와 같은 에러가 발생했다는 것은 대략 GDI 에 관련한 문제임을 직감할 수 있다. 따라서 디버깅을 하기 위해 작업관리자에서 GDI Objects 의 개수를 보여 주는 컬럼을 켠 상태에서 프로그램을 실행시켰다. 역시나, 객체 수가 계속 올라 간다. 즉, 문제는, GDI 객체가 제대로 해제되지 않아서 초반에는 프로그램이 잘 실행되는 것처럼 보이지만 객체수가 너무 많아질 경우 (보통 만개 직전) 컴퓨터 전체의 성능저하가 관찰되고 프로그램은 당연히 멈춘다 (같은 종류의 에러가 났을 때 컴퓨터의 상황). 그래서 그런 부분을 집중적으로 살펴 보았다. 



이런 경우 문제의 원인은 수도 없이 많을 것이며, 따라서 여기서 내가 말하는 것이 다는 아닐 것이다. 주로 ReleaseDC 나 Destroy 를 제대로 해주지 않아서 생기긴 할텐데, 그래도, 나의 경우 원인은 다음과 같았다. 



모니터의 해상도를 얻어 가기 위해 GetDeviceCaps API를 사용했는데, 그 때 ::GetDC 를 다음과 같이 사용했었다. 


int width = GetDeviceCaps(::GetDC(NULL),HORZRES);

int height = GetDeviceCaps(::GetDC(NULL),VERTRES);



NULL 이라 당연히 괜찮을 거라고 생각하고 있었는데 착각이었다. 그래서 다음과 같이 바꾸어 주니 해결되었다. 


HDC hDC = ::GetDC(NULL); 

// get monitor resolution. 

int width = GetDeviceCaps(hDC,HORZRES);

int height = GetDeviceCaps(hDC,VERTRES);

::ReleaseDC(NULL, hDC); 



요약하자면, 중요한 것은 프로그램이 잘 실행되다 멈추는 경우 자원의 반환이 제대로 일어나지 않아서 생겼을 가능성이 있으니 우선 그러한 부분부터 살펴 보아야 한다는 것이다. 파일을 열고 닫지 않은 상태에서 계속 다른 파일을 연다거나, 위처럼 GDI 객체의 자원을 사용 후 반환을 하지 않는다거나, 하는 등등.