diff --git a/core/libs/prx/libc/src/GuestArena.cpp b/core/libs/prx/libc/src/GuestArena.cpp index c14e34c81..b815e0fab 100644 --- a/core/libs/prx/libc/src/GuestArena.cpp +++ b/core/libs/prx/libc/src/GuestArena.cpp @@ -113,13 +113,19 @@ private: GetSystemInfo(&system); const std::uintptr_t granularity = system.dwAllocationGranularity; const std::uintptr_t end = ApplicationAreaEnd; + std::uint32_t retries = 0; for (std::uintptr_t cursor = ArenaStart; cursor < end;) { MEMORY_BASIC_INFORMATION info{}; if (VirtualQuery(reinterpret_cast(cursor), &info, sizeof(info)) == 0) throw std::system_error(static_cast(GetLastError()), std::system_category(), "query the guest arena range"); const auto regionEnd = std::min(end, reinterpret_cast(info.BaseAddress) + info.RegionSize); const auto first = info.State == MEM_FREE ? std::min(regionEnd, alignUp(cursor, granularity)) : regionEnd; const auto last = std::max(first, regionEnd & ~(granularity - 1)); - if (first < last && WindowsMappings::Get().Reserve(reinterpret_cast(first), last - first) == nullptr) throw std::system_error(static_cast(GetLastError()), std::system_category(), "reserve the guest arena range"); + if (first < last && WindowsMappings::Get().Reserve(reinterpret_cast(first), last - first) == nullptr) { + const auto error = GetLastError(); + if (error == ERROR_INVALID_ADDRESS && ++retries < 64u) continue; + throw std::system_error(static_cast(error), std::system_category(), "reserve the guest arena range"); + } + retries = 0; if (cursor < first) _holes.emplace_back(cursor, first); if (last < regionEnd) _holes.emplace_back(last, regionEnd); cursor = regionEnd;