From a960350e50f11813204fcb17656b692dceb9ae1c Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 26 Sep 2026 22:24:26 +0800 Subject: [PATCH] Fix windows leak when close PPSSPP by Gemini 'PPSSPPDebug64.exe' (Win32): Unloaded 'C:\Windows\System32\mfreadwrite.dll' The thread 'RecentISOThreadFunc' (9920) has exited with code 0 (0x0). The thread 'Console' (10488) has exited with code 0 (0x0). Detected memory leaks! Dumping objects -> {17571338} normal block at 0x00000214CC4A3FE0, 16 bytes long. Data: < Cf > E8 43 66 CD 14 02 00 00 00 00 00 00 00 00 00 00 {17571337} normal block at 0x00000214CC4A3B80, 16 bytes long. Data: < Cf > C8 43 66 CD 14 02 00 00 00 00 00 00 00 00 00 00 D:\project\memory_leak\ppsspp\Windows\Debugger\Debugger_Disasm.cpp(174) : {17571336} normal block at 0x00000214CD664190, 640 bytes long. Data: < C > 90 43 F2 C0 F6 7F 00 00 F6 0C 04 00 00 00 00 00 D:\project\memory_leak\ppsspp\UI\NativeApp.cpp(879) : {84582} normal block at 0x00000214CE8C5DB0, 4224 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {2432} normal block at 0x00000214D6255C20, 16 bytes long. Data: <0 $ > 30 E7 24 D6 14 02 00 00 00 00 00 00 00 00 00 00 D:\project\memory_leak\ppsspp\Common\Net\HTTPNaettRequest.cpp(43) : {2431} normal block at 0x00000214D624E730, 32 bytes long. Data: < \% > 20 5C 25 D6 14 02 00 00 00 00 00 00 00 00 00 00 Object dump complete. The thread 22000 has exited with code 0 (0x0). The thread 21248 has exited with code 0 (0x0). The thread 38104 has exited with code 0 (0x0). The thread 27860 has exited with code 0 (0x0). The thread 33240 has exited with code 0 (0x0). The thread 29352 has exited with code 0 (0x0). The thread 13964 has exited with code 0 (0x0). The thread 5640 has exited with code 0 (0x0). The thread 10528 has exited with code 0 (0x0). The thread 15252 has exited with code 0 (0x0). The thread 23016 has exited with code 0 (0x0). The thread 31424 has exited with code 0 (0x0). The thread 7000 has exited with code 0 (0x0). The thread 11620 has exited with code 0 (0x0). The thread 36264 has exited with code 0 (0x0). The thread 27248 has exited with code 0 (0x0). The thread 24780 has exited with code 0 (0x0). The thread 26228 has exited with code 0 (0x0). The thread 13676 has exited with code 0 (0x0). The thread 16828 has exited with code 0 (0x0). The thread 27388 has exited with code 0 (0x0). The thread 1668 has exited with code 0 (0x0). The thread 37272 has exited with code 0 (0x0). The program '[23456] PPSSPPDebug64.exe' has exited with code 0 (0x0). --- Common/Net/HTTPNaettRequest.cpp | 10 +++++++++- Common/Net/HTTPNaettRequest.h | 2 ++ Common/Net/Resolve.cpp | 4 ++++ UI/NativeApp.cpp | 12 +++++------- Windows/Debugger/Debugger_Disasm.cpp | 1 + 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Common/Net/HTTPNaettRequest.cpp b/Common/Net/HTTPNaettRequest.cpp index 4bbb2bd8ed..8161e6d92a 100644 --- a/Common/Net/HTTPNaettRequest.cpp +++ b/Common/Net/HTTPNaettRequest.cpp @@ -40,7 +40,12 @@ struct NaettBodySink { // while a callback might still be in flight, and neither can these, so both are deliberately // leaked. Allocated with new and never deleted, so it can't be destroyed out from under a late // callback during static destruction either. -static std::vector> *g_abandonedSinks = new std::vector>(); +static std::vector> *g_abandonedSinks = nullptr; + +void HTTPSShutdown() { + delete g_abandonedSinks; + g_abandonedSinks = nullptr; +} int HTTPSRequest::WriteBodyThunk(const void *source, int bytes, void *userData) { NaettBodySink *sink = (NaettBodySink *)userData; @@ -141,6 +146,9 @@ void HTTPSRequest::Join() { WARN_LOG(Log::HTTP, "Abandoning an unfinished request to '%s' - shutting down", url_.c_str()); if (sink_) { sink_->cancelled = true; + if (!g_abandonedSinks) { + g_abandonedSinks = new std::vector>(); + } g_abandonedSinks->push_back(std::move(sink_)); } res_ = nullptr; diff --git a/Common/Net/HTTPNaettRequest.h b/Common/Net/HTTPNaettRequest.h index 5c731678a5..37ade8521a 100644 --- a/Common/Net/HTTPNaettRequest.h +++ b/Common/Net/HTTPNaettRequest.h @@ -14,6 +14,8 @@ namespace http { struct NaettBodySink; +void HTTPSShutdown(); + // Really an asynchronous request. class HTTPSRequest : public Request { public: diff --git a/Common/Net/Resolve.cpp b/Common/Net/Resolve.cpp index e43192ee9d..60321e2420 100644 --- a/Common/Net/Resolve.cpp +++ b/Common/Net/Resolve.cpp @@ -15,6 +15,7 @@ #include "Common/Net/Resolve.h" #ifndef HTTPS_NOT_AVAILABLE +#include "Common/Net/HTTPNaettRequest.h" #include "ext/naett-lib/naett.h" // Note: PPSSPP_PLATFORM(LINUX) is also set on Android, which needs no loader. #if PPSSPP_PLATFORM(LINUX) && !PPSSPP_PLATFORM(ANDROID) @@ -68,6 +69,9 @@ bool HTTPSAvailable() { } void Shutdown() { +#ifndef HTTPS_NOT_AVAILABLE + http::HTTPSShutdown(); +#endif #ifdef _WIN32 if (g_wsaInitialized) { WSACleanup(); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 420e3061a5..504890ff10 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include "ext/imgui/imgui.h" @@ -872,15 +873,12 @@ bool CreateGlobalPipelines(); // TODO: Add faster special case for channels == 2. static void NativeMixWrapper(float *dest, int framesToWrite, int sampleRateHz, void *userdata) { - static int16_t *buffer; - static int bufSize; - if (bufSize < framesToWrite * 2) { - // This one leaks on exit. Oh well. - buffer = new int16_t[framesToWrite * 2]; - bufSize = framesToWrite * 2; + static std::vector buffer; + if ((int)buffer.size() < framesToWrite * 2) { + buffer.resize(framesToWrite * 2); } - NativeMix(buffer, framesToWrite, sampleRateHz, userdata); + NativeMix(buffer.data(), framesToWrite, sampleRateHz, userdata); for (int i = 0; i < framesToWrite * 2; i++) { dest[i] = (float)buffer[i] * (float)(1.0f / 32767.0f); diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 63d54d16de..199c272ae5 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -195,6 +195,7 @@ CDisasm::~CDisasm() delete threadList; delete stackTraceView; delete moduleList; + delete watchList_; } void CDisasm::step(CPUStepType stepType) {