AddressSanitizer 언어, 빌드 및 디버깅 참조
이 문서의 섹션에서는 AddressSanitizer 언어 사양, 컴파일러 옵션 및 링커 옵션에 대해 설명합니다. 또한 AddressSanitizer와 관련된 Visual Studio 디버거 통합을 제어하는 옵션도 설명합니다.
AddressSanitizer 런타임에 대한 자세한 내용은 런타임 참조를 참조하세요. 여기에는 가로채는 함수 및 사용자 지정 할당자를 후크하는 방법에 대한 정보가 포함됩니다. AddressSanitizer 오류에서 크래시 덤프를 저장하는 방법에 대한 자세한 내용은 크래시 덤프 참조를 참조하세요.
언어 사양
__SANITIZE_ADDRESS__
__SANITIZE_ADDRESS__
전처리기 매크로는 설정된 경우 /fsanitize=address
로 1
정의됩니다. 이 매크로는 고급 사용자가 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-coverage=edge
), - 인라인 8비트 카운터(
/fsanitize-coverage=inline-8bit-counters
), - 비교(
/fsanitize-coverage=trace-cmp
), - 정수 나누기(
/fsanitize-coverage=trace-div
).
와 함께 /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_기본 라이브러리 |
---|---|
/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하려면 다음을 수행해야 합니다.
- 옵션을 사용하여 컴파일합니다
/fsanitize-address-use-after-return
. - 프로그램을 실행하기 전에 실행
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_64
i386
동일한 아키텍처를 참조합니다.
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 오류 예제
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기