컨텐츠 바로가기

Asan(Address sanitizer, AddressSanitizer) 이란

http://rousalome.egloos.com/10025873

Asan은 Address sanitizer의 약자입니다. Address Sanitizer는 컴파일러를 수정해  프로그램이 동작하는 도중에 일어나는 잘못된 메모리 (주소) 액세스를 검출하기 위한 도구입니다. 

Git Hub

Asan에 대한 상세한 내용은 아래 깃허브에서 확인할 수 있습니다.

https://github.com/google/sanitizers/wiki/AddressSanitizer
 
Asan의 장점과 단점

사실 Asan과 비슷한 용도로 사용됐던 Valgrind라는 툴이 있습니다. 하지만 Valgrind는 치명적인 단점이 있습니다. 프로그램의 실행 속도가 매우 느려진다는 점인데, Valgrind이 모든 명령어를 에뮬레이션해 동작하기 때문입니다. 

그렇다면 Asan은 Valgrind보다 속도가 빠를까요? 네, 빠릅니다. 

Asan은 컴파일러의 도움을 받아, 이런 목적을 위한 코드를 해당 프로그램에 직접 삽입해 실행하기 때문입니다. 대신 프로그램을 재빌드해서 실행해야 하는 불편함이 있긴 합니다.

Asan의 핵심 동작

그렇다면, Asan의 핵심 동작은 무엇일까요?

정상적으로 접근 가능한 메모리 영역과 그렇지 않은 영역을 구분해, 올바르지 않은 영역을 접근하면(예: 메모리 관련 오류 발생, Fault) 이를 곧바로 탐지해서 알려주는 것입니다. 이를 위해 Asan은 컴파일러의 도움을 받게 됩니다. 정리하면, Asan은 메모리 주소에 엑세스할 때, 검사하는 작업을 수행하는 것입니다. 

엑세스하려는 주소가 올바른지 아닌지를 Asan은 어떻게 판단할까요?

shadow memory라는 추가적인 메모리를 사용해 validity를 검사합니다. 대부분 메모리 관련 오류는 주어진 영역을 벗어나서 다른 영역을 침범하는 경우(Out-of-bound)에 발생합니다. 그래서 메모리 영역 (변수) 사이 마다, red-zone이라는 영역을 추가해, 연속된 메모리 영역에 잘못된 접근해, 메모리 다른 영역이 침범당하는 경우를 찾아낼 수 있습니다. 즉, red-zone이 오염됐는지를 체크하는 것입니다.

Asan으로 잡아낼 수 있는 메모리 오류

Asan을 사용하면 모든 경우의 메모리 오류를 잡을 수 있을까요? 
그렇지는 않습니다. Asan을 사용해 검출할 수 있는 메모리 오류는 다음과 같습니다.

   * global/stack/heap 영역의 버퍼 오버플로우
   * heap use-after-free
   * stack use-after-return/scope

heap 영역은 libasan.so 라고 부르는 라이브러리를 통해 관리됩니다. 또한 global 영역과 stack 영역에 대해서는, 컴파일 시에 추가적인 작업이 필요한데, 이를 제어하기 위해서 '-asan-global' 및 '-asan-stack' 이라는 옵션을 제공합니다. 또한 실행 시에 제어가 가능한 기능들은 ASAN_OPTIONS라는 환경 변수를 통해 동적을 지정할 수 있습니다.



덧글|덧글 쓰기|신고