안녕하세요. 여기단 첨으로 글을 올리네요. 뭐 대단한 건 아니지만...
프로그램 하다 보면 가장 짜증날 때가 분명히 일어날 수 없는 일이라고 생각하고
있는 데 눈앞에서 버젓이 일어날 때 입니다. 버그죠. 프로그래머의 실수이든, 운
영 체제의 실수이든(근데 프로그래머 실수일 가능성이 높죠. 운영 체젠 비싸게 돈
주고 파는 거니까 오죽이나 잘 만들어 놓았겠습니까?) 버그 때문에 잠 설친 적이
하루 이틀이 아니죠. 그래서 제가 쓰는 디버깅 방법을 몇 자 적어 볼까 합니다.
우선, 모든 변수를 믿지 않죠. 분명 1,2 둘중에 하나다..라고 하더라도 믿지 않
습니다. 그래서 switch 문을 쓸 땐 항상 default, if 문을 쓸 땐 else를 넣죠. 함
수를 만들 경우, 전 우선 될 수 있으면 모든 함수의 리턴형을 불린으로 합니다.
CRgn 뭐 이런 걸로 리턴해야 한다면, 포인터 있으니까 포인터로 넘겨 버리죠. 그렇
게 한 다음, 함수의 첫머리에서 하는 일은 항상 그 함수 내에서 쓸 값들(보통 파라
미터가 되겠죠)의 유효성 검사 입니다. 말이 멋있는 데, 사실 별거 없구, if문으로
쭉 검사하는 거죠. 그 땐, 파일 첫머리에 #define _ENABLEERRORMESSAGE_ 이렇게 해
주고, if문 안에서
if(어쩌구 저쩌구 해서 false를 리턴해야 한다면){
#ifdef _ENABLEERRORMESSAGE_
AfxMessageBox(_T("에러에요. ~~~가 잘못되었네요^^"));
#endif
#ifdef _DEBUG
TRACE2(_T("%s(%d) : 에러 발견!! 내용 - 어쩌구~~~"),__FILE__,__LINE__);
#endif
return false;
}
이렇게 해주죠. TRACE구문은 컴파일 모드에 따라 알아서 컴파일 되겠지만, 명확히
할려구 저렇게 하구요. 저렇게 하고, 테스트 끝나면 #define _ENABLEERRORMESSAGE_
부분을 주석처리하죠. TRACE구문을 저렇게 하면(이 싸이트에서 봤는 데) 저 구문이
디버그 아웃풋 창에 나올 때 그 줄을 더블클릭하거나 F4를 누르면 저 줄로 캐럿이
이동하더군요. 또 컴파일 끝나면, Control + F5보단, 좀 느리지만, F5를 눌르죠.
그렇게 해서 에러나면, 메세지 박스 뜨잖아요. "취소" "재시도" "무시" 뭐 이런거
나오는 데, 그 때 "재시도" 누르면 어디서 에러가 났는 지 그 부분으로 이동하죠.
그 때 어쩔 땐 어셈 코드같은 게 나오는 데, 그 땐 디버그 툴 바 중에 CallStack창
띄워서 함수가 실행된 순서를 거꾸로 찾아가죠. 어셈 코드가 아니면 보통
ASSERT구문에서 걸리게 되는 데 그걸 보고 어디가 잘못되었는 지 알 수 있죠. 가령
ASSERT(::IsWindow(hWnd));에서 걸렸다면, 아직 윈도우가 만들어지지 않은 경우죠.
이런 건, PreCreateWindow같이, 윈도우를 만들기 전에 실행되는 함수에서
GetClientRect();같이 윈도우의 크기를 얻어갈려면 발생하겠죠. 포인터를 잘못 쓸
땐 그건 좀 어렵더라구요... mfc함수 중에도 불린형 값을 리턴하는 함수를 쓰면 그
뒤 바로 리턴값을 확인한답니다. 한번은 윈2000에서
CRgn rgn;
ASSERT(rgn.CreateRectRgn(0,0,0,0));
한 적이 있었는 데, 윈98로 가니까 에러가 나더라구요. 이 부분에서 걸린 겁니다.
윈98은 좌표값을 모두 0으로 주면 영역이 만들어지지 않았던 겁니다. 어쩔 땐
나만의 ASSERT구문을 만들기도 하죠. 이런 식으로도 에러를 못찾으면 적당한 곳에
브레이크포인트 걸어 놓구, 쭉 가다가 에러나는 곳에서 GetLastError();구문을
써서 무엇이 잘못되었는 지 알아가기도 합니다.
그럭저럭 제가 쓰는 디버깅 방법을 다 설명한 것 같네요...뭐가 더 있나?....지
금은 기억이 나질 않는군요. 예외 처리를 많이 해주면 처음엔 확실히 오래 걸리지
만 확실히 디버깅하긴 편하더라구요. 이것말구, 또 좋은 디버깅 방법 있으면 리
플좀 달아 주시구요. 그럼...
프로그램 하다 보면 가장 짜증날 때가 분명히 일어날 수 없는 일이라고 생각하고
있는 데 눈앞에서 버젓이 일어날 때 입니다. 버그죠. 프로그래머의 실수이든, 운
영 체제의 실수이든(근데 프로그래머 실수일 가능성이 높죠. 운영 체젠 비싸게 돈
주고 파는 거니까 오죽이나 잘 만들어 놓았겠습니까?) 버그 때문에 잠 설친 적이
하루 이틀이 아니죠. 그래서 제가 쓰는 디버깅 방법을 몇 자 적어 볼까 합니다.
우선, 모든 변수를 믿지 않죠. 분명 1,2 둘중에 하나다..라고 하더라도 믿지 않
습니다. 그래서 switch 문을 쓸 땐 항상 default, if 문을 쓸 땐 else를 넣죠. 함
수를 만들 경우, 전 우선 될 수 있으면 모든 함수의 리턴형을 불린으로 합니다.
CRgn 뭐 이런 걸로 리턴해야 한다면, 포인터 있으니까 포인터로 넘겨 버리죠. 그렇
게 한 다음, 함수의 첫머리에서 하는 일은 항상 그 함수 내에서 쓸 값들(보통 파라
미터가 되겠죠)의 유효성 검사 입니다. 말이 멋있는 데, 사실 별거 없구, if문으로
쭉 검사하는 거죠. 그 땐, 파일 첫머리에 #define _ENABLEERRORMESSAGE_ 이렇게 해
주고, if문 안에서
if(어쩌구 저쩌구 해서 false를 리턴해야 한다면){
#ifdef _ENABLEERRORMESSAGE_
AfxMessageBox(_T("에러에요. ~~~가 잘못되었네요^^"));
#endif
#ifdef _DEBUG
TRACE2(_T("%s(%d) : 에러 발견!! 내용 - 어쩌구~~~"),__FILE__,__LINE__);
#endif
return false;
}
이렇게 해주죠. TRACE구문은 컴파일 모드에 따라 알아서 컴파일 되겠지만, 명확히
할려구 저렇게 하구요. 저렇게 하고, 테스트 끝나면 #define _ENABLEERRORMESSAGE_
부분을 주석처리하죠. TRACE구문을 저렇게 하면(이 싸이트에서 봤는 데) 저 구문이
디버그 아웃풋 창에 나올 때 그 줄을 더블클릭하거나 F4를 누르면 저 줄로 캐럿이
이동하더군요. 또 컴파일 끝나면, Control + F5보단, 좀 느리지만, F5를 눌르죠.
그렇게 해서 에러나면, 메세지 박스 뜨잖아요. "취소" "재시도" "무시" 뭐 이런거
나오는 데, 그 때 "재시도" 누르면 어디서 에러가 났는 지 그 부분으로 이동하죠.
그 때 어쩔 땐 어셈 코드같은 게 나오는 데, 그 땐 디버그 툴 바 중에 CallStack창
띄워서 함수가 실행된 순서를 거꾸로 찾아가죠. 어셈 코드가 아니면 보통
ASSERT구문에서 걸리게 되는 데 그걸 보고 어디가 잘못되었는 지 알 수 있죠. 가령
ASSERT(::IsWindow(hWnd));에서 걸렸다면, 아직 윈도우가 만들어지지 않은 경우죠.
이런 건, PreCreateWindow같이, 윈도우를 만들기 전에 실행되는 함수에서
GetClientRect();같이 윈도우의 크기를 얻어갈려면 발생하겠죠. 포인터를 잘못 쓸
땐 그건 좀 어렵더라구요... mfc함수 중에도 불린형 값을 리턴하는 함수를 쓰면 그
뒤 바로 리턴값을 확인한답니다. 한번은 윈2000에서
CRgn rgn;
ASSERT(rgn.CreateRectRgn(0,0,0,0));
한 적이 있었는 데, 윈98로 가니까 에러가 나더라구요. 이 부분에서 걸린 겁니다.
윈98은 좌표값을 모두 0으로 주면 영역이 만들어지지 않았던 겁니다. 어쩔 땐
나만의 ASSERT구문을 만들기도 하죠. 이런 식으로도 에러를 못찾으면 적당한 곳에
브레이크포인트 걸어 놓구, 쭉 가다가 에러나는 곳에서 GetLastError();구문을
써서 무엇이 잘못되었는 지 알아가기도 합니다.
그럭저럭 제가 쓰는 디버깅 방법을 다 설명한 것 같네요...뭐가 더 있나?....지
금은 기억이 나질 않는군요. 예외 처리를 많이 해주면 처음엔 확실히 오래 걸리지
만 확실히 디버깅하긴 편하더라구요. 이것말구, 또 좋은 디버깅 방법 있으면 리
플좀 달아 주시구요. 그럼...