/

|

AddressSanitizer는 컴파일 때 넣는 런타임 검사로, 버퍼 오버플로와 use-after-free 같은 메모리 오류를 실행 중에 잡습니다.

이 글은 Clang AddressSanitizer 문서와 GCC Instrumentation Options, sanitizers wiki를 2026-08-30 기준으로 정리한 일반 설명이며, 플랫폼과 컴파일러 버전에 따라 세부 동작은 달라질 수 있습니다.

AddressSanitizer는 무엇입니까?

한 줄 답: 이 도구는 컴파일러 계측과 런타임 라이브러리로 메모리 오류를 실행 중에 찾는 검사입니다.

Clang 문서는 이를 C/C++용 빠른 메모리 오류 검출기로 설명하며, 공식 별칭으로 ASan이라고도 부릅니다. 핵심 구성은 컴파일러 계측 모듈과 런타임 라이브러리로 나뉩니다. 런타임 라이브러리는 malloc을 대체해 할당 관련 동작을 검사 흐름에 포함합니다.

컴파일러는 메모리 접근 명령을 계측하고, 실행 중 런타임이 접근 유효 범위를 확인합니다. 즉, 소스 코드만 읽어 판단하는 정적 분석기가 아니라, 검사 옵션을 넣어 빌드한 프로그램을 실제로 실행하면서 발생한 오류를 보고하는 방식입니다.

공식 문서가 안내하는 계측 프로그램의 전형적인 성능 저하는 약 2배입니다. 따라서 테스트 환경에서 실행할 때 실행 시간 증가와 메모리 부담을 반드시 함께 고려해야 합니다.

AddressSanitizer는 어떻게 켭니까?

한 줄 답: 컴파일과 링크에 -fsanitize=address를 넣고, 스택 추적을 위해 -fno-omit-frame-pointer를 함께 씁니다.

이 옵션은 각 소스 파일을 컴파일할 때와 최종 실행 파일을 링크할 때 모두 포함해야 합니다. 최종 링크 과정에서는 원시 ld 대신 clang, clang++ 또는 GCC 드라이버를 사용해야 이 도구의 런타임 라이브러리가 실행 파일에 정상적으로 연결됩니다.

-g 옵션은 디버깅 정보를 포함하고, -fno-omit-frame-pointer는 더 읽기 좋은 스택 추적에 도움을 줍니다. Clang 문서는 합리적인 실행 성능을 위해 -O1 이상 최적화를 권장하며, 완전한 스택 추적이 필요할 경우 -fno-optimize-sibling-calls로 형제·꼬리 호출 최적화를 막을 수 있다고 안내합니다.

clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc

ASAN_OPTIONS=help=1 환경 변수를 설정하면 프로그램 시작 시 사용할 수 있는 옵션 목록을 확인할 수 있습니다. 심볼을 사람이 읽기 편한 형태로 표시하려면 llvm-symbolizer를 PATH에 두거나 ASAN_SYMBOLIZER_PATH로 경로를 직접 지정할 수 있습니다.

AddressSanitizer는 어떤 오류를 잡습니까?

한 줄 답: 힙·스택·전역의 범위 초과 접근과 use-after-free, double-free 같은 메모리 오류를 실행 중에 보고합니다.

이 검사는 메모리 접근의 유효 범위와 할당 상태를 중심으로 이뤄집니다. 힙·스택·전역 버퍼의 범위 초과 접근, 해제 후 사용, 반환 후 사용, 스코프 후 사용이 대표적인 검사 대상입니다.

  • use-after-free: 해제된 메모리를 다시 사용하는 오류
  • heap-buffer-overflow, stack-buffer-overflow, global-buffer-overflow: 힙, 스택, 전역 버퍼 범위를 벗어난 잘못된 접근
  • use-after-return, use-after-scope: 반환되었거나 범위를 벗어난 로컬 저장 공간을 사용하는 오류
  • 초기화 순서 문제 (Initialization order bugs)
  • double-free, invalid free
  • 메모리 누수 (Memory leaks)

메모리 누수 검출은 현재 실험적 기능입니다. Linux에서는 기본으로 켜지고, macOS에서는 ASAN_OPTIONS=detect_leaks=1로 수동으로 켤 수 있으며, 그 밖의 플랫폼에서는 아직 지원되지 않습니다.

오류를 발견하면 표준 오류(stderr)에 원인 메시지를 출력하고 0이 아닌 종료 코드로 즉시 끝납니다. 기본 동작은 첫 번째 오류 발생 시 종료하는 것이며, 이는 설계상 의도된 방식입니다. 일반적인 검출에서는 오탐(False Positive)을 만들지 않는다고 Clang 문서가 설명하지만, 컨테이너 오버플로 추가 검사의 주의점은 다음 절에서 다룹니다.

AddressSanitizer가 못 잡거나 주의할 점은 무엇입니까?

한 줄 답: 정적 링크는 지원하지 않고, 프로덕션 실행 파일에 런타임을 넣는 용도가 아니며, 일부 접근은 최적화나 미계측 코드 때문에 놓칠 수 있습니다.

이 검사는 네이티브 실행보다 실제 메모리를 상당히 더 사용하며, 정확한 부담은 메모리 할당 크기에 따라 달라집니다. 할당 단위가 작을수록 오버헤드가 커질 수 있고, 스택 메모리는 최대 3배까지 증가한 사례가 문서에 제시되어 있습니다.

64비트 플랫폼에서는 16TB 이상 가상 주소 공간을 매핑하지만 실제로 예약하는 것은 아닙니다. 따라서 ulimit 같은 리소스 제한 도구가 평소와 다르게 동작할 수 있습니다.

실행 파일의 정적 링크는 지원하지 않습니다. 또한 런타임은 보안 민감한 제약을 고려해 개발된 것이 아니므로 프로덕션 실행 파일에 링크하는 용도가 아니라 오직 테스트 환경에 사용해야 합니다.

컴파일러가 명백히 잘못된 메모리 접근을 검사 전 최적화 단계에서 제거해 버리면 이 검사가 오류를 볼 수 없습니다. 모든 오류를 찾으려면 전체 구성 요소를 다시 빌드해야 하며, Clang 계측 코드와 GCC 계측 코드 또는 두 컴파일러의 런타임 구현을 서로 섞을 수 없습니다.

컨테이너 오버플로 추가 검사는 오탐 가능성이 있으므로, 앞서 말한 일반 검출의 특성과 명확히 구분해야 합니다. GCC 문서는 이 옵션을 -fsanitize=thread 또는 -fsanitize=hwaddress와 함께 사용할 수 없다고 안내합니다.

AddressSanitizer에 대해 자주 묻는 질문은 무엇입니까?

한 줄 답: 테스트 환경에서 빌드 방식과 런타임 제약을 함께 확인하면 됩니다.

질문 답변
프로덕션 바이너리에 이 런타임을 넣어도 됩니까? 버그 검출 도구이며 프로덕션 실행 파일에 링크하는 용도가 아니므로 테스트 환경에서 사용해야 합니다.
정적 링크와 함께 쓸 수 있습니까? 실행 파일의 정적 링크는 지원하지 않습니다.
일부 번역 단위만 다시 컴파일해도 됩니까? 일부만 다시 빌드해도 동작하지만, 모든 오류를 찾으려면 모든 구성 요소를 다시 빌드해야 합니다.
UBSan과 같은 검사입니까? 미정의 동작(UB) 검사는 다른 sanitizer 도구이며, 이 글의 대상인 메모리 오류 검사와는 다릅니다.

AddressSanitizer 공식 문서는 어디에 있습니까?

한 줄 답: 본문 사실과 짧은 빌드 명령은 2026-08-30 기준으로 확인한 공식 문서 세 곳만 사용합니다.

AddressSanitizer, commonly called ASan, instruments a C/C++ program during the build and checks memory use while that program runs. It is intended to expose bugs such as buffer overflows and use-after-free.

This is a general explanation based on the Clang AddressSanitizer documentation, GCC Instrumentation Options, and the sanitizers wiki, checked on 2026-08-30. Exact behavior can vary by platform and compiler version.

What does AddressSanitizer do?

Short answer: It combines compiler instrumentation with a runtime library to detect memory errors during execution.

Clang describes ASan as a fast memory-error detector for C and C++. Its two main pieces are the instrumentation added by the compiler and the runtime library that participates in allocation checks, including by replacing malloc.

The compiler adds checks around memory-access instructions, and the runtime verifies whether each access falls within a valid range while the instrumented program is running. That makes ASan a dynamic check: it reports errors exercised by a built program rather than judging the source code without running it like a static analyzer.

The official documentation gives roughly a two-times slowdown as a typical cost for an instrumented program. Testing therefore needs to account for both longer execution and higher memory use.

Which compiler flags enable AddressSanitizer?

Short answer: Add -fsanitize=address when compiling and linking, and pair it with -fno-omit-frame-pointer for more useful stack traces.

The sanitizer option must be present when each source file is compiled and again when the final executable is linked. Use the clang, clang++, or GCC driver for that final link instead of invoking the raw ld, so the sanitizer runtime is linked into the executable correctly.

-g includes debugging information, while -fno-omit-frame-pointer helps keep stack traces readable. Clang recommends at least -O1 for reasonable execution performance; when a complete stack trace is needed, -fno-optimize-sibling-calls can prevent sibling or tail-call optimization.

clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc

Set ASAN_OPTIONS=help=1 to print the available runtime options when the program starts. For readable symbol names, put llvm-symbolizer on PATH or provide its location through ASAN_SYMBOLIZER_PATH.

Which memory errors can AddressSanitizer find?

Short answer: It reports out-of-bounds accesses in heap, stack, and global storage, along with errors such as use-after-free and double-free, when execution reaches them.

ASan focuses on whether a memory access is within a valid range and whether the allocation is still live. Typical targets include overflows of heap, stack, and global buffers, use after free, use after return, and use after scope.

  • use-after-free: using memory again after it has been freed
  • heap-buffer-overflow, stack-buffer-overflow, and global-buffer-overflow: accessing beyond a heap, stack, or global buffer
  • use-after-return and use-after-scope: using local storage after a function has returned or after its scope has ended
  • Initialization-order bugs
  • double-free and invalid free
  • Memory leaks

Leak detection is still experimental. It is enabled by default on Linux, can be enabled manually on macOS with ASAN_OPTIONS=detect_leaks=1, and is not yet supported on the other platforms described by the documentation.

When ASan finds an error, it prints a diagnostic to standard error and terminates immediately with a nonzero exit code. Stopping at the first error is the intentional default design. Clang describes ordinary detection as not producing false positives, but additional container-overflow checks require separate caution, as discussed below.

What are AddressSanitizer’s limitations?

Short answer: It does not support static linking, is meant for test builds rather than production executables, and can miss accesses removed by optimization or occurring in uninstrumented code.

An instrumented program uses substantially more real memory than a native run, and the exact cost depends on the size of its allocations. Smaller allocation units can increase overhead; the documentation gives examples in which stack memory grows by as much as three times.

On 64-bit platforms, ASan maps more than 16 TB of virtual address space, although that space is not actually reserved in full. As a result, resource-limit tools such as ulimit may behave differently from an ordinary run.

Static linking of the executable is not supported. The runtime is also not designed for security-sensitive constraints, so it should be used only in a test environment, not linked into a production executable.

If the compiler removes an obviously invalid memory access during optimization before ASan can instrument it, ASan cannot report that error. To find all relevant errors, rebuild the complete set of components. Do not mix Clang-instrumented code with GCC-instrumented code, or mix the runtime implementations from the two compilers.

Additional container-overflow checks can produce false positives, so they should be distinguished clearly from the ordinary detection behavior described earlier. GCC also documents that this option cannot be used together with -fsanitize=thread or -fsanitize=hwaddress.

What questions do developers ask about AddressSanitizer?

Short answer: Check the build method and the runtime constraints together when deciding how to use it.

Question Answer
Can the runtime be included in a production binary? It is a bug-detection tool rather than a runtime intended for production executables, so use it in a test environment.
Can AddressSanitizer be used with static linking? Static linking of the executable is not supported.
Is recompiling only some translation units enough? A partial rebuild can run, but finding all errors requires rebuilding all components.
Is AddressSanitizer the same as UBSan? Undefined-behavior checking is provided by a different sanitizer; this article covers memory-error checking.

Which official sources document AddressSanitizer?

Short answer: The factual claims and short build command here use only three official documents checked on 2026-08-30.

  • Clang AddressSanitizer — Covers the overview, usage, detection scope, performance and memory limits, and security considerations.
  • Google sanitizers wiki: AddressSanitizer — Used to check the C/C++ error list, the complete-component rebuild requirement, and the restriction against mixing implementations.
  • GCC Instrumentation Options — Used to check -fsanitize=address, stack-trace-related flags, ASAN_OPTIONS, and sanitizer-combination restrictions.

+ Recent posts