디버깅 대화상자를 통해서 메모리 오류 판별하기

2006-07-13 신영진

1. Introduction

활성화된 프로그램관련 질답 게시판을 보면 반복적으로 늘 올라오는 질문중의 하나가 메모리 오류에 관한 것이다. 실무에 사용되는 대부분의 상용 프로그램들도 포인터/메모리 관련 코드들이 프로그램의 전체 오류의 90% 이상을 차지한다고 해도 과언이 아니다. 실무 프로그램이 이 정도니 처음 작성하는 사람들이 포인터 오류를 피한다는 것은 그야말로 힘들다고 할 수 있다. 또한 오류 상황을 보고 대처하는 방법을 모르기 때문에 더욱 난처한 경우가 많다. 아마도 그래서 질답 게시판에는 그렇게나 자주 뜬금없는 질문들이 많이 올라오는 것으로 보인다.

이 문서는 오류가 나는 코드를 살펴보고, 해당 코드가 실행될 때 발생하는 오류를 알아 봄으로써 추후에 동일한 에러가 난 경우에 좀 더 빨리 디버깅 할 수 있는 능력 배양에 그 목적이 있다 하겠다... ㅎㅎㅎ~ 그럼 지금부터 처음 프로그램을 작성하는 분들이 자주 접하는 메모리 오류 상황에 대해서 살펴보도록 하자~

2. Heap overrun

첫 번째는 메모리 영역을 넘어서 오버라이트 한 경우이다. 다음과 같은 코드를 생각할 수 있다.

보면 100개를 할당하고 나서는 stupid_func에서 200개를 초기화 해버리고 있다. 할당된 것 보다 더 많이 써서 오버라이트 되 버린 것이다. 디버그 중이라면 아래와 같은 ASSERT 진단 오류를 만날 수 있다.

3. Heap header overwrite

두번째로 할당된 메모리 이전 영역을 겹쳐쓰는 경우이다. 다음과 같은 코드를 생각할 수 있다.

보면 할당이 시작된 주소 이전(ar-100)에서 부터 값을 채우기 때문에 라이브러리에서 내부적으로 사용하는 관리 헤더 부분을 초기화 시킬 수 있다. 디버그 중이라면 아래와 같은 ASSERT 진단 오류를 만날 수 있다.

4. More...

아래는 위의 것과 유사한 오류가 날 수 있는 더 많은 상황들을 정리해 보았다. 늘 항상 포인터를 다룰때에는 아래와 같은 점검 목록을 머릿속으로 생각하는 것을 게을리 하지 말아야 할 것이다.

5. Conclusion

C++을 사용한다면 되도록 날(Raw) 포인터를 사용하지 않는 것이 좋다고 한다. 그리고 날(Raw) 포인터를 사용해야 한다면 그 놈이 사용되는 코드 주위는 항상 감시하도록 하자!