錯誤: 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
範例 - 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++和範本
另請參閱
AddressSanitizer 概觀
AddressSanitizer 已知問題
AddressSanitizer 組建和語言參考
AddressSanitizer 運行時間參考
AddressSanitizer 陰影位元組
AddressSanitizer 雲端或分散式測試
AddressSanitizer 調試程式整合
AddressSanitizer 錯誤範例