如何修复Payday 2 BLT模组中的Lua Stack Overflow错误?
Let's break down your issues step by step and work through fixes:
1. Root Cause of the Initial Stack Overflow
The stack overflow on line 13 (local _id = "id_" .. tostring(self._id)) is almost certainly tied to one of two problems:
- Circular references in
self._id: Ifself._idis a table with a circular reference (e.g., it points back to itself or another table that loops back to it),tostring()will recursively traverse the table until the stack runs out of space. - Infinite recursive calls: Your custom
on_executedhook calls the original function at the end, but if yourRun_Scriptlogic triggers anotheron_executedcall (like invoking the mission element's ownon_executedmethod), this creates an infinite loop that piles up function calls until the stack overflows.
Fix for Stack Overflow
Add a guard to block recursive execution, and handle self._id safely to avoid circular reference crashes:
core:module("CoreMissionScriptElement") core:import("CoreXml") core:import("CoreCode") core:import("CoreClass") _G.ShadowRaidLoud = _G.ShadowRaidLoud or {} ShadowRaidLoud = _G.ShadowRaidLoud ShadowRaidLoud.Run_Script_Data = ShadowRaidLoud.Run_Script_Data or {} local ShadowRaidLoud_OpenVault = MissionScriptElement.on_executed function MissionScriptElement:on_executed(instigator, ...) -- Guard against recursive hook calls if self._shadow_raid_executing then return ShadowRaidLoud_OpenVault(self, instigator, ...) end self._shadow_raid_executing = true -- Safely handle self._id to avoid circular reference crashes local _id local id_type = type(self._id) if id_type == "number" or id_type == "string" then _id = "id_" .. self._id else _id = "id_unknown" -- Optional: Log the issue for debugging log("[ShadowRaidLoud] Unexpected _id type: " .. id_type .. " for element: " .. tostring(self)) end if ShadowRaidLoud and ShadowRaidLoud.Enable and not Network:is_client() and not Global.loading then if (_id == "id_100961" or _id == "id_100962") and not ShadowRaidLoud.Run_Script_Data[_id] then local element = self:get_mission_element(100964) if element then local msg = "[System] Vault will open in ".. ShadowRaidLoud.Time4Use.OpenVault .." seconds" ShadowRaidLoud:Announce(msg) local _tmp = ShadowRaidLoud:Run_Script("id_100964", self, 100964, element, instigator, ShadowRaidLoud.Time4Use.OpenVault) ShadowRaidLoud.Run_Script_Data["id_100961"] = _tmp ShadowRaidLoud.Run_Script_Data["id_100962"] = _tmp end end end -- Call the original function ShadowRaidLoud_OpenVault(self, instigator, ...) -- Clear the guard flag self._shadow_raid_executing = nil end
Key improvements here:
- Added a
_shadow_raid_executingflag to block recursive hook execution - Added type checking for
self._idto avoidtostring()on circular tables - Added
not Global.loadingto skip logic during loading (directly addresses your access violation issue)
2. Fixing the Access Violation
The access violation in the LoadingEnvironment thread happens because your code was trying to access game systems that aren't fully initialized yet during the loading phase. Calls like Network:is_client() and get_mission_element() aren't safe to run while the game is still loading—they can attempt to read uninitialized memory, causing the crash.
The not Global.loading check added above ensures your custom logic only runs when the game has finished loading, preventing these unsafe memory accesses.
Additional Best Practices
- Use BLT's Hook API: Instead of manually overriding the function, consider using BLT's
Hook:PostHookwhich handles calling the original function automatically and reduces recursion risk:Hook:PostHook(MissionScriptElement, "on_executed", "ShadowRaidLoud_OnExecuted", function(self, instigator, ...) -- Your custom logic here (runs after the original on_executed) -- No need to call the original function manually end) - Add debug logging: If you're still troubleshooting, add log statements to track when your code runs and what values
self._idhas:log("[ShadowRaidLoud] Executed element with _id: " .. tostring(self._id) .. " type: " .. type(self._id))
内容的提问来源于stack exchange,提问作者DarkCeptor44

