From 7be243a8b4fcaefc88ed59d8bfc3f875f5b440dd Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Wed, 11 Mar 2026 11:25:59 -0700 Subject: [PATCH] Common/MemArena: make shared memory name unique per DLL instance When multiple copies of the same DLL are loaded into the same process (e.g. for libretro multi-instance support), all copies share the same PID. Using only the PID as the name suffix caused CreateFileMapping to return the existing named kernel object instead of creating a new one, so both instances silently mapped the same 4GB+ GameCube/Wii RAM region and instantly corrupted each other. Fix this by also embedding the address of a static-local variable in the name. Because each DLL copy is mapped at a different base address in the process, s_dll_id lives at a unique virtual address in every copy, so its value acts as a stable, zero-cost, per-instance discriminator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Source/Core/Common/MemArenaWin.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Core/Common/MemArenaWin.cpp b/Source/Core/Common/MemArenaWin.cpp index 4c296da631..9be5cd4648 100644 --- a/Source/Core/Common/MemArenaWin.cpp +++ b/Source/Core/Common/MemArenaWin.cpp @@ -120,7 +120,14 @@ static DWORD GetLowDWORD(u64 value) void MemArena::GrabSHMSegment(size_t size, std::string_view base_name) { - const std::string name = fmt::format("{}.{}", base_name, GetCurrentProcessId()); + // Include the address of a static local as a per-DLL-instance unique ID. + // When multiple copies of this DLL are loaded in the same process they share + // the same PID, so we need an additional discriminator. Each copy is mapped + // at a different base address, so s_dll_id's address (and thus its value) is + // unique per loaded instance. + static const uintptr_t s_dll_id = reinterpret_cast(&s_dll_id); + const std::string name = + fmt::format("{}.{}.{:x}", base_name, GetCurrentProcessId(), s_dll_id); m_memory_handle = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, GetHighDWORD(size), GetLowDWORD(size), UTF8ToTStr(name).c_str());