오류: stack-use-after-return
삭제자 오류 해결: 반환 후 스택 메모리 사용
이 검사를 수행하려면 추가 컴파일러 옵션 /fsanitize-address-use-after-return
및 환경 변수 ASAN_OPTIONS=detect_stack_use_after_return=1
를 설정하여 활성화된 코드 생성이 필요합니다.
이 검사를 수행하면 애플리케이션 속도가 상당히 느려질 수 있습니다. 반환 후 사용을 지원하는 알고리즘의 Clang 요약과 더 큰 성능 비용을 고려합니다.
Important
추가 컴파일러 옵션을 /fsanitize-address-use-after-return
사용하여 개체 파일을 만드는 경우 컴파일러에서 생성된 코드는 스택 프레임을 할당하는 방법에 대한 런타임 결정을 내립니다. 환경 변수 ASAN_OPTIONS
가 설정 detect_stack_use_after_return
되지 않은 경우 코드는 자체에서 사용하는 /fsanitize=address
것보다 느립니다. 사용 하 여 alloca()
프레임의 일부에 대 한 공간을 할당 하는 일부 스택 프레임에서 추가 오버 헤드가 여전히 있기 때문에 속도가 느립니다. 반환 후 사용 오류 처리가 완료되면 이러한 개체 파일을 삭제하는 것이 가장 좋습니다.
예제 - Simple C
// example1.cpp
// stack-use-after-return error
volatile char* x;
void foo() {
char stack_buffer[42];
x = &stack_buffer[13];
}
int main() {
foo();
*x = 42; // Boom!
return (*x == 42);
}
이 예제를 빌드하고 테스트하려면 Visual Studio 2019 버전 16.9 이상 개발자 명령 프롬프트에서 다음 명령을 실행합니다.
cl example1.cpp /fsanitize=address /fsanitize-address-use-after-return /Zi
set ASAN_OPTIONS=detect_stack_use_after_return=1
devenv /debugexe example1.exe
결과 오류 - 단순 C
예제 - C++ 및 템플릿
// example2.cpp
// stack-use-after-return error
#include <stdlib.h>
enum ReadOrWrite { Read = 0, Write = 1 };
struct S32 {
char x[32];
};
template<class T>
T* LeakStack() {
T t[100];
static volatile T* x;
x = &t[0];
return (T*)x;
}
template<class T>
void StackUseAfterReturn(int Idx, ReadOrWrite w) {
static T sink;
T* t = LeakStack<T>();
if (w)
t[100 + Idx] = T();
else
sink = t[100 + Idx];
}
int main(int argc, char* argv[]) {
if (argc != 2) return 1;
int kind = atoi(argv[1]);
switch (kind) {
case 1: StackUseAfterReturn<char>(0, Read); break;
case 2: StackUseAfterReturn<S32>(0, Write); break;
}
return 0;
}
이 예제를 빌드하고 테스트하려면 Visual Studio 2019 버전 16.9 이상 개발자 명령 프롬프트에서 다음 명령을 실행합니다.
cl example2.cpp /fsanitize=address /fsanitize-address-use-after-return /Zi /Od
set ASAN_OPTIONS=detect_stack_use_after_return=1
devenv /debugexe example2.exe 1
ASAN은 동적 분석의 한 형태이므로 실제로 실행되는 잘못된 코드만 검색할 수 있습니다. 최적화 프로그램에서 값 t[100 + Idx]
이 사용되거나 sink
사용되지 않는지 확인하고 할당을 취소할 수 있습니다. 따라서 이 예제에는 플래그가 /Od
필요합니다.
결과 오류 - C++ 및 템플릿
참고 항목
AddressSanitizer 개요
AddressSanitizer 알려진 문제
AddressSanitizer 빌드 및 언어 참조
AddressSanitizer 런타임 참조
AddressSanitizer 섀도 바이트
AddressSanitizer 클라우드 또는 분산 테스트
AddressSanitizer 디버거 통합
AddressSanitizer 오류 예제