From 994960627bf75bf7a380f0540a60966700146dfd Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 21 Oct 2019 15:54:13 +0300 Subject: [PATCH] - added explicit clearing of global VM stask When exception is thrown from JITed code, VM stask isn't cleared during unwinding It needs to be clear explicitly to avoid memory leaks and references to destructed objects on shutdown https://forum.zdoom.org/viewtopic.php?t=66172 --- src/d_main.cpp | 1 + src/playsim/dthinker.cpp | 1 + src/scripting/vm/vm.h | 2 ++ src/scripting/vm/vmframe.cpp | 8 ++++++++ 4 files changed, 12 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index d4003fbd2..90efa16ab 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -984,6 +984,7 @@ void D_ErrorCleanup () } if (gamestate == GS_INTERMISSION) gamestate = GS_DEMOSCREEN; insave = false; + ClearGlobalVMStack(); } //========================================================================== diff --git a/src/playsim/dthinker.cpp b/src/playsim/dthinker.cpp index 8ef9659e5..16b7f666f 100644 --- a/src/playsim/dthinker.cpp +++ b/src/playsim/dthinker.cpp @@ -250,6 +250,7 @@ void FThinkerCollection::DestroyAllThinkers() GC::FullGC(); if (error) { + ClearGlobalVMStack(); I_Error("DestroyAllThinkers failed"); } } diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index 49bb51704..db55dce43 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -110,6 +110,8 @@ public: void ThrowAbortException(EVMAbortException reason, const char *moreinfo, ...); void ThrowAbortException(VMScriptFunction *sfunc, VMOP *line, EVMAbortException reason, const char *moreinfo, ...); +void ClearGlobalVMStack(); + struct VMReturn { void *Location; diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index f8916e94a..7c2a63b1f 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -715,6 +715,14 @@ void ThrowVMException(VMException *x) #endif +void ClearGlobalVMStack() +{ + while (GlobalVMStack.PopFrame() != nullptr) + { + } +} + + ADD_STAT(VM) { double added = 0;