==15348==ERROR: AddressSanitizer: stack-use-after-...

Criado em: 22 de abril de 2026

Respondido usando GPT-5.4 Thinking por Chat01

Pergunta

==15348==ERROR: AddressSanitizer: stack-use-after-scope on address 0x007b14dfd900 at pc 0x7ffcec059b16 bp 0x007b14dfd8e0 sp 0x007b14dfd8e8
WRITE of size 8 at 0x007b14dfd900 thread T0
#0 0x7ffcec059b15 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 0x7ffcebe4e059 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 0x7ffcebfea42a 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 0x7ffcec06a0c4 in AgpInit E:\TEST_AGP\TEST_FUNC\TEST_FUNC.cpp:4730
#4 0x7ffceab427dc (<unknown module>)

Address 0x007b14dfd900 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:
0x007b14dfd680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfd700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfd780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfd800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfd880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x007b14dfd900:[f8]f1 f1 f1 00 f2 f8 f2 f8 f2 f8 f3 f3 f3 f3 00
0x007b14dfd980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfda00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x007b14dfda80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
0x007b14dfdb00: f1 f1 01 f2 01 f2 f8 f2 00 f2 00 f2 f8 f3 f3 f3
0x007b14dfdb80: f3 00 00 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) __declspec(noalias) _forceinline 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);

Pensamento

Похоже, проблема не в std::wstring ws(buf) как таковой, а в том, что компилятору дали неверные обещания об этой функции. У вас самый подозрительный момент — __declspec(noalias) на AgpInit(): эта функция активно работает с глобалами, кучей, Python, WinAPI и MPI, а noalias для такого кода применять нельзя.

Thought for 19s

Resposta

Ошибка почти наверняка не в строке

cpp
std::wstring ws(buf);

сама по себе. Эта строка просто первая, где ASan заметил поломку памяти. Настоящая причина у вас, скорее всего, вот здесь:

cpp
extern "C" __declspec(dllexport) __declspec(noalias) __forceinline int AgpInit() noexcept

Что здесь не так

__declspec(noalias) для AgpInit() использовать нельзя.

Эта функция:

  • пишет в глобальные переменные g_env, g_world, g_exeDirCache, g_pyInterpreter, g_pyOptimizerBridge
  • делает new
  • вызывает WinAPI
  • работает с Python runtime
  • работает с MPI

То есть функция совсем не соответствует смыслу noalias. Из-за этого оптимизатор MSVC может сделать некорректные предположения о памяти, и AddressSanitizer потом ловит уже последствия — например, как будто std::wstring строится поверх “умершего” стека.

Почему ASan показывает именно std::wstring ws(buf)

Потому что в этот момент идет запись во внутренности std::wstring, и ASan видит доступ к уже отравленной области стека. Но это не значит, что виноват buf или конструктор wstring. Это типичный симптом более ранней порчи памяти или неверной оптимизации.


Что сделать сразу

Уберите оба атрибута, хотя критичен именно noalias:

cpp
extern "C" __declspec(dllexport) int AgpInit() noexcept {

Или хотя бы так:

cpp
extern "C" __declspec(dllexport) int AgpInit() noexcept

__forceinline на экспортируемой функции тоже лишний и только усложняет отладку.


Самая вероятная причина

Вот самая вероятная версия:

  1. __declspec(noalias) сообщает компилятору слишком сильные гарантии.
  2. Компилятор переставляет/оптимизирует работу со стеком и объектами.
  3. ASan видит обращение к памяти, которая уже помечена как stack-use-after-scope.
  4. Падает на строке std::wstring ws(buf);, хотя реальный источник — неверная аннотация функции.

Дополнительно: есть еще 2 опасных места

1. ws.resize(pos);

Если вдруг find_last_of не найдет слэш, pos == std::wstring::npos, и это уже UB/исключение/крах.

Лучше так:

cpp
const auto pos = ws.find_last_of(L"\\/"); if (pos == std::wstring::npos) { return -1; } ws.resize(pos);

2. WideCharToMultiByte

У вас логика в целом нормальная, но лучше проверить результат:

cpp
const int n = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, nullptr, 0, nullptr, nullptr); if (n <= 0) { return -2; } g_exeDirCache.resize(static_cast<size_t>(n)); const int written = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, g_exeDirCache.data(), n, nullptr, nullptr); if (written <= 0) { return -3; } g_exeDirCache.pop_back();

Как бы я переписал ваш фрагмент

cpp
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"\\/"); if (pos == std::wstring::npos) { return -1; } ws.resize(pos); const int n = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), -1, nullptr, 0, nullptr, nullptr); if (n <= 0) { return -2; } g_exeDirCache.resize(static_cast<size_t>(n)); const int written = WideCharToMultiByte( CP_UTF8, 0, ws.c_str(), -1, g_exeDirCache.data(), n, nullptr, nullptr ); if (written <= 0) { return -3; } 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; }

Главное

Сначала попробуйте только одно изменение:

cpp
extern "C" __declspec(dllexport) int AgpInit() noexcept

То есть убрать:

  • __declspec(noalias)
  • __forceinline

Очень вероятно, что после этого ASan-падение на std::wstring ws(buf); исчезнет.

Если хотите, я могу дальше разобрать именно семантику __declspec(noalias) в MSVC и показать, почему для такой функции это UB-подобная ловушка.

Compartilhar esta Q&A