From cc1fe800739b8240f9e47d64f475212566cd6b7c Mon Sep 17 00:00:00 2001 From: Kris Austin Date: Tue, 21 Jul 2026 13:43:55 -0500 Subject: [PATCH] fix: out-of-memory on Windows crashes with no dialog and a misleading stack (#14807) --- src/OrcaSlicer.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 9db1aea5f8..e0a15209a3 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #if defined(__linux__) || defined(__LINUX__) #include @@ -7608,6 +7610,9 @@ LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) }*/ #if defined(_MSC_VER) || defined(__MINGW32__) +// Guards against a failed allocation inside the dump re-entering the new-handler. +static std::atomic g_dump_in_progress{false}; + extern "C" { __declspec(dllexport) int __stdcall orcaslicer_main(int argc, wchar_t **argv) { @@ -7626,10 +7631,22 @@ extern "C" { //AddVectoredExceptionHandler(1, CBaseException::UnhandledExceptionFilter); SET_DEFULTER_HANDLER(); #endif + // Dump before unwinding, while the stack still names what asked for the memory. Throwing + // std::bad_alloc is standard-permitted here and is what reaches generic_exception_handle(). std::set_new_handler([]() { - int *a = nullptr; - *a = 0; - }); + if (!g_dump_in_progress.exchange(true)) { + try { + // A null EXCEPTION_POINTERS walks the calling thread as it stands. + CBaseException base(GetCurrentProcess(), GetCurrentProcessId(), NULL, nullptr); + base.ShowCallstack(); + } catch (...) { + // A failed dump must not displace the std::bad_alloc owed to the caller. + } + // ObjParser recovers from std::bad_alloc, so let a later one dump again. + g_dump_in_progress = false; + } + throw std::bad_alloc(); + }); // Call the UTF8 main. return CLI().run(argc, argv_ptrs.data()); }