다음을 통해 공유


오류: 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

예제 1에서 스택 사용 후 오류를 표시하는 디버거의 스크린샷

예제 - 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++ 및 템플릿

예제 2에서 스택 사용 후 오류를 표시하는 디버거의 스크린샷

참고 항목

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