1/29/2009

익셉션(exception)과 메모리 릭(memory leak)

C++에는 전통적인 C의 플로우 콘트롤 패쓰의 개념을 넘어서는 익셉션(exception)이라는 개념이 있다. 처음 나는 C를 배울 때에 익셉션이라는 개념 자체를 배우지 않아서 약간의 거부감을 가지고 있다. 하지만 C++로 개발하다 보면 익셉션이라는 개념은 너무나도 많이 사용되고, 또한 편리함도 많은 가져다 준다. 또한 버퍼 오버플로우 취약점을 exploit하기 위해서도 사용되는 좋은 녀석이다. 더 좋은 것은 이 익셉션 핸들링이 윈도우즈 커널 모듈 프로그래밍에서도 지원된다는 것이다.
그런데 이 익세셥 처리를 잘못하면 메모리 릭을 유발하는 경우가 있다라는 것을 이제서야 체험하게 되었다. 고객사에서 자꾸 메모리 릭을 호소하는데, 그 릭킹이 일어나는 풀택(PoolTag)을 아무리 찾아 봐도 논리적인 흐름상 꼭 메모리가 해제되도록 되어 있다. 그런데 단 한가지 내가 간과한 것은 바로 코드 어느 부분에서든지 익셉션이 일어 날 수 있다는 점이다. 코드의 최상위층에서는 모든 익셉션을 핸들링 하고 있으므로 그 익셉션은 조용히 처리되어서 넘어 간다. 대신 메모리가 해제 되지 않는 일이 발생하는 것이다.
결자 해지라고 익셉션으로 발생한 메모리 릭은 또한 try-finally라는 구문을 써서 해결할 수 있다. finally 블럭에 메모리 해지 루틴을 넣어 두면 익셉션이 발생하건 정상적으로 리턴하건 간에 그 블럭에 있는 "termination statement"를 무조건 호출하게 되어 있다. 그 부분에 ExFreePool을 넣어 주면 되는 것이다.
 
"""
The compound statement after the __try clause is the guarded section. The compound statement after the __finally clause is the termination handler. The handler specifies a set of actions that execute when the guarded section is exited, regardless of whether the guarded section is exited by an exception (abnormal termination), or by standard fall through (normal termination).
"""
 
커널 랜드에서는 간단한 메모리 접근조차도 익셉션을 일으키는 경우가 많으므로 메모리 해지시에는 try-finally를 쓰는 것을 습관화하는 것이 아무래도 골치 썪을 일을 줄이는 방법인듯 하다.

Posted via email from bugtruck's posterous

댓글 1개:

  1. 스콧마이어의 Effective C++ 책을 외울 정도로 봐야 C++의 각종 함정에 대비할 수 있더라구요. 보면 볼수록 어려운 언어, C++

    답글삭제