共用方式為


錯誤: stack-use-after-return

位址清理程式錯誤:傳回之後使用堆疊記憶體

這項檢查需要額外的編譯程式選項所啟動的程式代碼產生, /fsanitize-address-use-after-return以及藉由設定環境變數 ASAN_OPTIONS=detect_stack_use_after_return=1

這項檢查可能會大幅降低您的應用程式速度。 請考慮支持在傳回之後使用的演算法 Clang 摘要,以及較大的效能成本。

重要

如果您使用額外的編譯程式選項 /fsanitize-address-use-after-return建立物件檔,則編譯程式所產生的程式代碼會決定如何配置堆疊框架。 如果環境變數 ASAN_OPTIONS 未設定為 detect_stack_use_after_return,則程式代碼仍然比單獨使用 /fsanitize=address 慢。 速度較慢,因為某些堆疊框架仍有額外的額外負荷,這些堆疊框架會使用 alloca()來配置框架部分的空間。 當您完成處理傳回後使用錯誤時,最好刪除這些物件檔案。

範例 - 簡單 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 是一種動態分析形式,這表示它只能偵測實際執行錯誤的程序代碼。 優化器可能會判斷 或 sink 的值t[100 + Idx]永遠不會使用,並降低指派。 因此,此範例需要 /Od 旗標。

產生的錯誤 - C++和範本

顯示範例 2 中堆疊使用後傳回錯誤的調試程式的螢幕快照。

另請參閱

AddressSanitizer 概觀
AddressSanitizer 已知問題
AddressSanitizer 組建和語言參考
AddressSanitizer 運行時間參考
AddressSanitizer 陰影位元組
AddressSanitizer 雲端或分散式測試
AddressSanitizer 調試程式整合
AddressSanitizer 錯誤範例