==14392==ERROR: AddressSanitizer: stack-use-after-...
創建於:2026年4月22日
使用 GPT-5.4 Thinking 回答 Chat01
創建於:2026年4月22日
使用 GPT-5.4 Thinking 回答 Chat01
==14392==ERROR: AddressSanitizer: stack-use-after-scope on address 0x00f55fdfd810 at pc 0x7ffce6529b16 bp 0x00f55fdfd7f0 sp 0x00f55fdfd7f8
WRITE of size 8 at 0x00f55fdfd810 thread T0
#0 0x7ffce6529b15 in std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class std::allocator<wchar_t>>::max_size(void) const C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\xstring:2288
#1 0x7ffce631e059 in std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class std::allocator<wchar_t>>::_Construct<1, wchar_t const *>(wchar_t const *const, unsigned __int64) C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\xstring:931
#2 0x7ffce64ba42a in std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class std::allocator<wchar_t>>::basic_string<wchar_t, struct std::char_traits<wchar_t>, class std::allocator<wchar_t>>(wchar_t const *const) C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\xstring:819
#3 0x7ffce653a0c4 in AgpInit E:\TEST_AGP\TEST_FUNC\TEST_FUNC.cpp:4730
#4 0x7ffceab527dc (<unknown module>)
Address 0x00f55fdfd810 is located in stack of thread T0
SUMMARY: AddressSanitizer: stack-use-after-scope C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\xstring:2288 in std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class std::allocator<wchar_t>>::max_size(void) const
Shadow bytes around the buggy address:
0x00f55fdfd580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00f55fdfd800: 00 00[f8]f1 f1 f1 00 f2 f8 f2 f8 f2 f8 f3 f3 f3
0x00f55fdfd880: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfd980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f55fdfda00: f1 f1 f1 f1 01 f2 01 f2 f8 f2 00 f2 00 f2 f8 f3
0x00f55fdfda80: f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb - получаю ошибку, где - extern "C" _declspec(dllexport) int AgpInit() noexcept {
g_env = new boost::mpi::environment();
g_world = new boost::mpi::communicator();
MM_SET_FLUSH_ZERO_MODE(MM_FLUSH_ZERO_ON);
MM_SET_DENORMALS_ZERO_MODE(MM_DENORMALS_ZERO_ON);
const int rank = g_world->rank();
if (rank == 0) {
wchar_t buf[MAX_PATH]{};
GetModuleFileNameW(nullptr, buf, MAX_PATH);
std::wstring ws(buf);
const auto pos = ws.find_last_of(L"\/");
ws.resize(pos);
const int n = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, nullptr, 0, nullptr, nullptr);
g_exeDirCache.resize(static_cast<size_t>(n));
WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, g_exeDirCache.data(), n, nullptr, nullptr);
g_exeDirCache.pop_back();
g_pyInterpreter = new pybind11::scoped_interpreter{};
pybind11::module sys = pybind11::module::import("sys");
pybind11::list path = sys.attr("path");
const std::string& exeDir = g_exeDirCache;
path.attr("insert")(0, pybind11::str(exeDir + "\env\Lib\site-packages"));
path.attr("insert")(0, pybind11::str(exeDir + "\env\Scripts"));
path.attr("insert")(0, pybind11::str(exeDir + "\env"));
path.attr("append")(pybind11::str(exeDir));
pybind11::module::import("warnings").attr("filterwarnings")("ignore");
g_pyOptimizerBridge = new pybind11::module(pybind11::module::import("optimizer_bridge"));
}
return rank;
}, а строка 4730 это std::wstring ws(buf);
Нет, проблема, скорее всего, не в std::wstring ws(buf); самой по себе.
По вашему ASan-логу важнее вот это:
stack-use-after-scopef8 = Stack use after scopestd::wstring, но это часто означает, что к моменту создания ws уже испорчен стек или используется ссылка/указатель на локальный объект, который уже умер.То есть строка
cppstd::wstring ws(buf);
обычно здесь жертва, а не источник.
Если бы проблема была в buf, вы бы чаще увидели что-то вроде:
А тут ASan говорит, что идет запись в область стека, которая уже считается вышедшей из scope. Это очень похоже на один из сценариев:
GetModuleFileNameW и нуль-терминаторВот это место небезопасно:
cppwchar_t buf[MAX_PATH]{}; GetModuleFileNameW(nullptr, buf, MAX_PATH); std::wstring ws(buf);
GetModuleFileNameW не гарантирует нуль-терминатор, если путь был обрезан по MAX_PATH.
Надо делать так:
cppwchar_t buf[MAX_PATH]{}; DWORD len = GetModuleFileNameW(nullptr, buf, MAX_PATH); if (len == 0 || len >= MAX_PATH) { return -1; // или ваш код ошибки } std::wstring ws(buf, len);
Это не очень похоже на ваш stack-use-after-scope, но это все равно баг, который надо исправить.
ws.resize(pos);Если find_last_of не найдет \\ или /, то pos == std::wstring::npos, и resize(pos) — это уже UB/исключение.
Надо:
cppconst auto pos = ws.find_last_of(L"\\/"); if (pos == std::wstring::npos) { return -2; } ws.resize(pos);
Вот это безопасно:
cppconst std::string& exeDir = g_exeDirCache;
потому что g_exeDirCache — не локальная переменная.
Но очень похоже, что вокруг AgpInit или до него есть код, где:
wchar_t* на локальный буферstd::wstring_view / std::string_view на временную строкуstd::string / std::wstringИ потом это бьет стек, а проявляется уже на std::wstring ws(buf).
С высокой вероятностью:
ошибка находится не на строке 4730, а раньше — в коде, который повредил стек или оставил висячую ссылку на локальный объект.
cppextern "C" __declspec(dllexport) int AgpInit() noexcept { g_env = new boost::mpi::environment(); g_world = new boost::mpi::communicator(); _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); const int rank = g_world->rank(); if (rank == 0) { wchar_t buf[MAX_PATH] = {}; DWORD len = GetModuleFileNameW(nullptr, buf, MAX_PATH); if (len == 0 || len >= MAX_PATH) { return -1; } std::wstring ws(buf, len); const auto pos = ws.find_last_of(L"\\/"); if (pos == std::wstring::npos) { return -2; } ws.resize(pos); const int n = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, nullptr, 0, nullptr, nullptr); if (n <= 0) { return -3; } g_exeDirCache.resize(static_cast<size_t>(n - 1)); WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, g_exeDirCache.data(), n, nullptr, nullptr); g_pyInterpreter = new pybind11::scoped_interpreter{}; pybind11::module_ sys = pybind11::module_::import("sys"); pybind11::list path = sys.attr("path"); const std::string& exeDir = g_exeDirCache; path.attr("insert")(0, pybind11::str(exeDir + "\\env\\Lib\\site-packages")); path.attr("insert")(0, pybind11::str(exeDir + "\\env\\Scripts")); path.attr("insert")(0, pybind11::str(exeDir + "\\env")); path.attr("append")(pybind11::str(exeDir)); pybind11::module_::import("warnings").attr("filterwarnings")("ignore"); g_pyOptimizerBridge = new pybind11::module_(pybind11::module_::import("optimizer_bridge")); } return rank; }
noexceptУ вас функция объявлена как:
cppextern "C" __declspec(dllexport) int AgpInit() noexcept
Но внутри вызывается куча вещей, которые могут бросить исключение:
newstd::wstringstd::string::resizepybind11::module_::importpybind11::scoped_interpreterЕсли там вылетает исключение, при noexcept вы получите std::terminate, и отладка будет сильно путаться.
На время диагностики лучше убрать noexcept или хотя бы обернуть всё в try/catch.
Например:
cppextern "C" __declspec(dllexport) int AgpInit() { try { ... } catch (const std::exception& e) { return -100; } catch (...) { return -101; } }
string_view / wstring_viewconst char* / const wchar_t*c_str() от временной строкиAgpInit и могло испортить стекОсобенно ищите такое:
cppconst wchar_t* p = someLocalWstring.c_str(); // плохо, если someLocalWstring потом умирает std::wstring_view v = local_wstring; // плохо, если view живет дольше строки global_ref = local_string; // плохо, если это ссылка
По вашему логу:
bufstd::wstring ws(buf); — скорее место проявленияGetModuleFileNameWnposnoexcept на время диагностикиЕсли хотите, я могу дальше помочь точечно: разберу весь AgpInit построчно и покажу, какие места в нём реально опасны, а какие нет.