다음을 통해 공유


AddressSanitizer 언어, 빌드 및 디버깅 참조

이 문서의 섹션에서는 AddressSanitizer 언어 사양, 컴파일러 옵션 및 링커 옵션에 대해 설명합니다. 또한 AddressSanitizer와 관련된 Visual Studio 디버거 통합을 제어하는 옵션도 설명합니다.

AddressSanitizer 런타임에 대한 자세한 내용은 런타임 참조를 참조하세요. 여기에는 가로채는 함수 및 사용자 지정 할당자를 후크하는 방법에 대한 정보가 포함됩니다. AddressSanitizer 오류에서 크래시 덤프를 저장하는 방법에 대한 자세한 내용은 크래시 덤프 참조참조하세요.

언어 사양

__SANITIZE_ADDRESS__

__SANITIZE_ADDRESS__ 전처리기 매크로는 설정된 경우 /fsanitize=address1 정의됩니다. 이 매크로는 고급 사용자가 AddressSanitizer 런타임의 존재에 대한 소스 코드를 조건부로 지정하는 데 유용합니다.

#include <cstdio>

int main() {
    #ifdef __SANITIZE_ADDRESS__
        printf("Address sanitizer enabled");
    #else
        printf("Address sanitizer not enabled");
    #endif
    return 1;
}

__declspec(no_sanitize_address)

__declspec(no_sanitize_address) 지정자는 함수, 지역 변수 또는 전역 변수에서 소독제를 선택적으로 사용하지 않도록 설정하는 데 사용할 수 있습니다. 이는 __declspec 런타임 동작이 아니라 컴파일러 동작에 영향을 줍니다.

__declspec(no_sanitize_address)
void test1() {
    int x[100];
    x[100] = 5; // ASan exception not caught
}

void test2() {
    __declspec(no_sanitize_address) int x[100];
    x[100] = 5; // ASan exception not caught
}

__declspec(no_sanitize_address) int g[100];
void test3() {
    g[100] = 5; // ASan exception not caught
}

컴파일러

/fsanitize=address 컴파일러 옵션

/fsanitize=address 컴파일러 옵션은 코드에서 메모리 참조를 계측하여 런타임에 메모리 안전 오류를 catch합니다. 계측 후크는 로드, 저장소, 범위 alloca및 CRT 함수를 연결합니다. 범위를 벗어난 버그, 사용 후 사용, 사용 후 범위 등과 같은 숨겨진 버그를 검색할 수 있습니다. 런타임에 검색된 비동기 오류 목록은 AddressSanitizer 오류 예제를 참조 하세요.

/fsanitize=address는 모든 기존 C++ 또는 C 최적화 수준(예: /Od, , /O1/O2및)과 /O2 /GL호환됩니다. 이 옵션으로 생성된 코드는 정적 및 동적 CRT(예: /MD, /MDd, /MT/MTd)에서 작동합니다. 이 컴파일러 옵션을 사용하여 x86 또는 x64를 대상으로 하는 .EXE 또는 .DLL 만들 수 있습니다. 호출 스택의 최적의 서식을 지정하려면 디버그 정보가 필요합니다. 이 컴파일러 옵션은 프로필 기반 최적화에서 지원되지 않습니다.

여러 종류의 오류 검색을 보여 주는 코드의 예제는 AddressSanitizer 오류 예제를 참조 하세요.

/fsanitize=fuzzer 컴파일러 옵션(실험적)

/fsanitize=fuzzer 컴파일러 옵션은 LibFuzzer를 기본 라이브러리 목록에 추가합니다. 또한 다음과 같은 소독제 검사 옵션을 설정합니다.

와 함께 /fsanitize=fuzzer사용하는 /fsanitize=address 것이 좋습니다.

다음을 지정 /fsanitize=fuzzer하면 이러한 라이브러리가 기본 라이브러리 목록에 추가됩니다.

런타임 옵션 LibFuzzer 라이브러리
/MT clang_rt.fuzzer_MT-{arch}
/MD clang_rt.fuzzer_MD-{arch}
/MTd clang_rt.fuzzer_MTd-{arch}
/MDd clang_rt.fuzzer_MDd-{arch}

함수를 생략 main 하는 LibFuzzer 라이브러리도 사용할 수 있습니다. 이러한 라이브러리를 정의 main 하고 호출 LLVMFuzzerInitialize 하는 것은 사용자의 책임입니다 LLVMFuzzerTestOneInput . 이러한 라이브러리 중 하나를 사용하려면 런타임 및 아키텍처에 해당하는 다음 라이브러리를 지정 /NODEFAULTLIB 하고 명시적으로 연결합니다.

런타임 옵션 LibFuzzer no_main 라이브러리
/MT clang_rt.fuzzer_no_main_MT-{arch}
/MD clang_rt.fuzzer_no_main_MD-{arch}
/MTd clang_rt.fuzzer_no_main_MTd-{arch}
/MDd clang_rt.fuzzer_no_main_MDd-{arch}

지정 /NODEFAULTLIB 하고 이러한 라이브러리 중 하나를 지정하지 않으면 해결되지 않은 외부 기호 링크 오류가 발생합니다.

/fsanitize-address-use-after-return 컴파일러 옵션(실험적)

기본적으로 MSVC 컴파일러(Clang와 달리)는 반환 후 사용 오류를 catch하기 위해 힙의 프레임을 할당하는 코드를 생성하지 않습니다. AddressSanitizer를 사용하여 이러한 오류를 catch하려면 다음을 수행해야 합니다.

  1. 옵션을 사용하여 컴파일합니다 /fsanitize-address-use-after-return .
  2. 프로그램을 실행하기 전에 실행 set ASAN_OPTIONS=detect_stack_use_after_return=1 하여 런타임 확인 옵션을 설정합니다.

/fsanitize-address-use-after-return 옵션을 사용하면 로컬이 "주소 사용"으로 간주될 때 컴파일러가 힙에서 이중 스택 프레임을 사용하는 코드를 생성합니다. 이 코드는 단독으로 사용하는 /fsanitize=address 것보다 훨씬 느립니다. 자세한 내용 및 예제 는 오류: stack-use-after-return.

힙의 이중 스택 프레임은 힙을 만든 함수에서 반환된 후에도 유지됩니다. 힙의 슬롯에 할당된 로컬 주소가 반환 후에 사용되는 예를 생각해 보세요. 가짜 힙 프레임과 연결된 섀도 바이트에는 0xF9 값이 포함됩니다. 이 0xF9 런타임에서 오류를 보고할 때 스택 사용 후 반환 오류를 의미합니다.

스택 프레임은 힙에 할당되며 함수가 반환된 후에도 유지됩니다. 런타임은 가비지 수집을 사용하여 특정 시간 간격 후에 이러한 가짜 호출 프레임 개체를 비동기적으로 해제합니다. 로컬 주소는 힙의 영구 프레임으로 전송됩니다. 정의 함수가 반환된 후 로컬이 사용되는 시기를 시스템에서 감지하는 방법입니다. 자세한 내용은 Google에서 설명한 대로 반환 후 스택 사용 알고리즘을 참조하세요.

링커

/INFERASANLIBS[:NO] 링커 옵션

/fsanitize=address 컴파일러 옵션은 실행 파일에 연결할 AddressSanitizer 라이브러리를 지정하는 개체를 표시합니다. 라이브러리에는 .로 clang_rt.asan*시작하는 이름이 있습니다. 링커 옵션(기본적으로 설정)은 /INFERASANLIBS 이러한 라이브러리를 기본 위치에서 자동으로 연결합니다. 선택한 라이브러리와 자동으로 연결된 라이브러리는 다음과 같습니다.

참고 항목

다음 표 {arch} 에서 중 하나 i386 또는 x86_64. 이러한 라이브러리는 아키텍처 이름에 Clang 규칙을 사용합니다. MSVC 규칙은 일반적으로 x86 x64 및 대신.x86_64i386 동일한 아키텍처를 참조합니다.

CRT 옵션 AddressSanitizer 런타임 라이브러리(.lib) 주소 런타임 이진(.dll)
/MT 또는 /MTd clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}
/MD 또는 /MDd clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}

링커 옵션을 /INFERASANLIBS:NO 사용하면 링커가 기본 위치에서 라이브러리 파일을 연결할 clang_rt.asan* 수 없습니다. 이 옵션을 사용하는 경우 빌드 스크립트에 라이브러리 경로를 추가합니다. 그렇지 않으면 링커가 확인되지 않은 외부 기호 오류를 보고합니다.

이전 버전

Visual Studio 17.7 미리 보기 3 이전에는 정적으로 연결된(/MT 또는 /MTd) 빌드에서 DLL 종속성을 사용하지 않았습니다. 대신 AddressSanitizer 런타임이 사용자의 EXE에 정적으로 연결되었습니다. 그런 다음 DLL 프로젝트는 사용자의 EXE에서 내보내기를 로드하여 ASan 기능에 액세스합니다. 또한 동적으로 연결된 프로젝트(/MD 또는 /MTd)는 프로젝트가 디버그 또는 릴리스에 대해 구성되었는지 여부에 따라 다른 라이브러리 및 DLL을 사용했습니다. 이러한 변경 내용 및 해당 동기에 대한 자세한 내용은 MSVC Address Sanitizer – 모든 런타임 구성에 대한 하나의 DLL을 참조 하세요.

CRT 런타임 옵션 DLL 또는 EXE AddressSanitizer 런타임 라이브러리
/MT EXE clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
/MT DLL clang_rt.asan_dll_thunk-{arch}
/MD 여기서는 clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch}
/MTd EXE clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch}
/MTd DLL clang_rt.asan_dbg_dll_thunk-{arch}
/MDd 여기서는 clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

Visual Studio 통합

/fno-sanitize-address-vcasan-lib 컴파일러 옵션

/fsanitize=address 옵션은 AddressSanitizer 예외가 throw될 때 향상된 Visual Studio 디버깅 환경을 위해 추가 라이브러리에 연결됩니다. 이러한 라이브러리를 VCAsan이라고 합니다. 라이브러리를 사용하면 Visual Studio에서 소스 코드에 AddressSanitizer 오류를 표시할 수 있습니다. 또한 AddressSanitizer 오류 보고서를 만들 때 실행 파일에서 크래시 덤프를 생성할 수 있습니다. 자세한 내용은 Visual Studio AddressSanitizer 확장 기능 라이브러리를 참조하세요.

선택한 라이브러리는 컴파일러 옵션에 따라 달라지고 자동으로 연결됩니다.

런타임 옵션 VCAsan 버전
/MT libvcasan.lib
/MD vcasan.lib
/MTd libvcasand.lib
/MDd vcasand.lib

그러나 (기본 라이브러리 이름 생략)을 사용하여 /Zl 컴파일하는 경우 라이브러리를 수동으로 지정해야 합니다. 그렇지 않으면 해결되지 않은 외부 기호 링크 오류가 발생합니다. 다음은 몇 가지 일반적인 예입니다.

error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib

향상된 디버깅은 이 옵션을 사용하여 /fno-sanitize-address-vcasan-lib 컴파일 시간에 사용하지 않도록 설정할 수 있습니다.

ASAN_VCASAN_DEBUGGING환경 변수

/fsanitize=address 컴파일러 옵션은 런타임에 메모리 안전 버그를 노출하는 이진 파일을 생성합니다. 명령줄에서 이진 파일이 시작되고 런타임에서 오류를 보고하면 오류 세부 정보가 출력됩니다. 그런 다음 프로세스를 종료합니다. 런타임에서 ASAN_VCASAN_DEBUGGING 오류를 보고하는 즉시 Visual Studio IDE를 시작하도록 환경 변수를 설정할 수 있습니다. 이 컴파일러 옵션을 사용하면 오류를 발생시킨 정확한 줄과 열에서 소스 코드 위에 중첩된 오류를 볼 수 있습니다.

이 동작을 사용하도록 설정하려면 애플리케이션을 실행하기 전에 명령을 set ASAN_VCASAN_DEBUGGING=1 실행합니다. 를 실행 set ASAN_VCASAN_DEBUGGING=0하여 향상된 디버깅 환경을 사용하지 않도록 설정할 수 있습니다.

참고 항목

AddressSanitizer 개요
AddressSanitizer 알려진 문제
AddressSanitizer 런타임 참조
AddressSanitizer 섀도 바이트
AddressSanitizer 클라우드 또는 분산 테스트
AddressSanitizer 디버거 통합
AddressSanitizer 오류 예제