エラー: stack-use-after-scope
Address Sanitizer エラー: スコープ外スタック メモリの使用
変数の有効期間の構文スコープ外でスタック アドレスを使用すると、C または C++ でさまざまな方法で発生する可能性があります。
例 1 - 単純な入れ子になったローカル
// example1.cpp
// stack-use-after-scope error
int *gp;
bool b = true;
int main() {
if (b) {
int x[5];
gp = x+1;
}
return *gp; // Boom!
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe
結果のエラー: 単純な入れ子になったローカル
例 2 - ラムダ キャプチャ
// example2.cpp
// stack-use-after-scope error
#include <functional>
int main() {
std::function<int()> f;
{
int x = 0;
f = [&x]() {
return x; // Boom!
};
}
return f(); // Boom!
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe
結果のエラー: ラムダ キャプチャ
例 3 - ローカルでのデストラクターの順序付け
// example3.cpp
// stack-use-after-scope error
#include <stdio.h>
struct IntHolder {
explicit IntHolder(int* val = 0) : val_(val) { }
~IntHolder() {
printf("Value: %d\n", *val_); // Bom!
}
void set(int* val) { val_ = val; }
int* get() { return val_; }
int* val_;
};
int main(int argc, char* argv[]) {
// It's incorrect to use "x" inside the IntHolder destructor,
// because the lifetime of "x" ends earlier. Per the C++ standard,
// local lifetimes end in reverse order of declaration.
IntHolder holder;
int x = argc;
holder.set(&x);
return 0;
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example3.cpp /fsanitize=address /Zi /O1
devenv /debugexe example3.exe
結果のエラー: デストラクターの順序付け
例 4 - 一時
// example4.cpp
// stack-use-after-scope error
#include <iostream>
struct A {
A(const int& v) {
p = &v;
}
void print() {
std::cout << *p;
}
const int* p;
};
void explicit_temp() {
A a(5); // the temp for 5 is no longer live;
a.print();
}
void temp_from_conversion() {
double v = 5;
A a(v); // local v is no longer live.
a.print();
}
void main() {
explicit_temp();
temp_from_conversion();
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example4.cpp /EHsc /fsanitize=address /Zi /Od
devenv /debugexe example4.exe
ASAN は動的分析の一種であり、実際に実行された不適切なコードのみを検出できることを意味します。 このような場合、オプティマイザーは、p
に格納されているアドレスから読み取る代わりに、v
の値を伝達できます。 その結果、この例では /Od
フラグが必要です。
結果のエラー: 一時エラー
関連項目
AddressSanitizer の概要
AddressSanitizer の既知の問題
AddressSanitizer のビルドと言語リファレンス
AddressSanitizer ランタイム リファレンス
AddressSanitizer シャドウ バイト
AddressSanitizer クラウドまたは分散テスト
AddressSanitizer デバッガーの統合
AddressSanitizer エラーの例