【问题标题】:How to fix 'Stack Overflow' error in Lua?如何修复 Lua 中的“堆栈溢出”错误?
【发布时间】:2019-12-17 09:34:28
【问题描述】:

我正在尝试修复导致游戏崩溃的 Payday 2 BLT mod,但我是 modding 和 Lua 的初学者,作者一年多没有更新它,我设法找到了崩溃到脚本的第 13 行:

这是错误:

Application has crashed: C++ exception
mods/ShadowRaidLoud/lua/coremissionscriptelement.lua:13: stack overflow

据我了解,tostring(self._id) 可能会导致错误,但我不知道从这里该怎么做。

这是发薪日 2 模组,移除模组可能会阻止崩溃,但我希望自己修复它。尝试联系作者,但没有成功。

coremissionscriptelement.lua:

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, ...)
    local _id = "id_" .. tostring(self._id)   -- stack overflow crash here
    if ShadowRaidLoud and ShadowRaidLoud.Enable and not Network:is_client() 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
    ShadowRaidLoud_OpenVault(self, instigator, ...)
end

编辑:我尝试将 return 添加到函数的最后一行,但它仍然导致此崩溃日志崩溃:

Application has crashed: access violation

-------------------------------

Callstack:

         payday2_win32_release  (???)     ???                                                 


-------------------------------

Current thread: LoadingEnvironment

-------------------------------

System information:
    Application version : 1.92.790
    CPU : Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz (2 cores); SSE; SSE2; SSE3; SSSE3; SSE4.1; SSE4.2
    DirectX : 12.0 
    GPU : NVIDIA GeForce GTX 1070 / nvldumd.dll[26.21.14.3160]
    Language : english
    Memory :     16269MB 264KB
    OS : 6.1.7600 () 0x300-0x1 (64 bits)
    Physics : threaded
    Renderer : DX9 threaded
    Sound : Realtek Semiconductor Corp. (Speakers (Realtek High Definition Audio))

【问题讨论】:

  • MissionScriptElement:on_executed 调用ShadowRaidLoud_OpenVault 等于MissionScriptElement.on_executed。小心使用递归(否则 ouroboros 会导致程序中的堆栈溢出)

标签: lua stack-overflow


【解决方案1】:

很难测试这是否是唯一的问题,但是由于(正如@Egor 已经提到的)hadowRaidLoud_OpenVault == MissionScriptElement.on_executed,您应该在ShadowRaidLoud_OpenVault(self, instigator, ...) 之前放置一个 return 语句以将其转换为正确的尾调用:

function MissionScriptElement:on_executed(instigator, ...)
    --- SNIP ---
    return ShadowRaidLoud_OpenVault(self, instigator, ...)
end

至少该递归不应再次导致堆栈溢出,只要它不断满足尾调用的要求。

【讨论】:

  • 哦,好吧,我试着去掉最后一点,但它仍然崩溃,所以我要尝试返回它,因为我注意到作为参数传递的三个点是否真的存在于 Lua 中?在其他语言中,它被用作编写每一个语言的替代方案。
  • @DarkCeptor44 是的,... 捕获给函数的任何附加参数,如果使用它也必须在参数列表中。如果跟踪调用不够,您可能有循环事件。
  • 它没有用,它仍然崩溃,但这次日志更没有帮助,日志只说访问冲突。
猜你喜欢
  • 1970-01-01
  • 2012-01-04
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2020-09-11
  • 2016-01-23
相关资源
最近更新 更多