WeaselGames / godot_luaAPI

Godot LuaAPI
https://luaapi.weaselgames.info
Other
371 stars 28 forks source link

Godot crashes when running a lua script which gets a node in a loop. #75

Closed waleed177 closed 1 year ago

waleed177 commented 1 year ago

Describe the bug Godot 4.0 v4.0.beta.custom_build [0b1d516f6] with the master branch of luaapi commit (https://github.com/WeaselGames/godot_luaAPI/commit/eda1c454411bf8fbb9c5e85f291e4868344ea3a3), crashed when getting a node in a loop then yielding in a loop.

To Reproduce Make a scene with one node inside it called Node, attach to the scene this script:

extends Node3D

@export_multiline var source: String = ""

var lua_api
var lua: LuaThread
class WaitObject:
    var time = 0

var _yieldTime = 0
var _timeSince = 0
# Called when the node enters the scene tree for the first time.
func _ready():
    _ready2.call_deferred()

func _ready2():
    lua_api = LuaAPI.new()
    lua_api.bind_libraries(["base", "math", "coroutine"])
    lua = LuaThread.new_thread(lua_api)
    lua.expose_constructor("WaitObject", WaitObject)
    lua.push_variant("node", self)
    lua.load_string("""
function wait(time)
    local res = WaitObject()
    res.time = time
    yield (res)
end
    """)
    _resume_once()

    lua.load_string("""
    while true do
        wait(0.01)
        print("before get node")
        local p = node.get_node("Node")
        print("after get node")
    end
    """)
    _process(1)

func _process(delta):
    _timeSince += delta
    if not lua: return
    if lua.is_done():
        queue_free()
        return
    if _timeSince <= _yieldTime:
        return

    var ret = lua.resume()
    if ret is LuaError:
        print(ret.message)
        return
    elif ret is Array and len(ret) == 1:
        var obj = ret[0]
        if obj is WaitObject:
            _yieldTime = obj.time
            _timeSince = 0

func _resume_once():
    var res = lua.resume()
    if res is LuaError:
        print(res.message)

I do note that it doesnt crash when getting the node, it crashes when reaching the end of the loop as this is the output ( i truncated the start, since its all the same):

before get node
after get node
before get node
after get node
before get node
after get node

this is the crash report:

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.beta.custom_build (0b1d516f67a3b2b7dd158b923559f192ec103a85)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /usr/lib/libc.so.6(+0x38a00) [0x7fcf2228fa00] (??:0)
[2] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x130b14f) [0x55a80de3a14f] (??:0)
[3] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x135e213) [0x55a80de8d213] (??:0)
[4] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1322cde) [0x55a80de51cde] (??:0)
[5] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x132bf92) [0x55a80de5af92] (??:0)
[6] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x131c95b) [0x55a80de4b95b] (??:0)
[7] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1320950) [0x55a80de4f950] (??:0)
[8] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1320ae6) [0x55a80de4fae6] (??:0)
[9] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x132209c) [0x55a80de5109c] (??:0)
[10] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x132279a) [0x55a80de5179a] (??:0)
[11] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x133aeb9) [0x55a80de69eb9] (??:0)
[12] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x135f58b) [0x55a80de8e58b] (??:0)
[13] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1322cde) [0x55a80de51cde] (??:0)
[14] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1323aa8) [0x55a80de52aa8] (??:0)
[15] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1330057) [0x55a80de5f057] (??:0)
[16] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x131c95b) [0x55a80de4b95b] (??:0)
[17] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x13366f9) [0x55a80de656f9] (??:0)
[18] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x1315598) [0x55a80de44598] (??:0)
[19] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xebe32f) [0x55a80d9ed32f] (??:0)
[20] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xffa47e) [0x55a80db2947e] (??:0)
[21] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xea37ed) [0x55a80d9d27ed] (??:0)
[22] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x2d0dba4) [0x55a80f83cba4] (??:0)
[23] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x32310bd) [0x55a80fd600bd] (??:0)
[24] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x4c32b54) [0x55a811761b54] (??:0)
[25] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x2d3d13e) [0x55a80f86c13e] (??:0)
[26] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0x2d3f00f) [0x55a80f86e00f] (??:0)
[27] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xb488fd) [0x55a80d6778fd] (??:0)
[28] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xadf281) [0x55a80d60e281] (??:0)
[29] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xad1219) [0x55a80d600219] (??:0)
[30] /usr/lib/libc.so.6(+0x23290) [0x7fcf2227a290] (??:0)
[31] /usr/lib/libc.so.6(__libc_start_main+0x8a) [0x7fcf2227a34a] (??:0)
[32] /home/genericuser/Documents/GodotEditorBuilds/godot/bin/godot.linuxbsd.editor.x86_64(+0xadd415) [0x55a80d60c415] (??:0)
-- END OF BACKTRACE --
================================================================

Expected behavior It shouldnt crash.

Screenshots N/A

Environment

Trey2k commented 1 year ago

Thanks for the report! Just ran a quick test, this does not cause a crash on windows with the nightly build. Which is likely built with an older version of godot. Can you test if the Linux nightly build has this bug as well? So we can see if this is a upstream change causing the issue or platform specific issue.

Trey2k commented 1 year ago

Scratch that, I was mistaken. I misread the part where you said it does not crash until the end of the loop. Can confirm its reproducible.

Trey2k commented 1 year ago

Okay so the issue causing this is the attempted integration ive done with the lua garbage collector. https://github.com/WeaselGames/godot_luaAPI/blob/eda1c454411bf8fbb9c5e85f291e4868344ea3a3/src/metatables.cpp#L450-L457 Lua's GC tries to clean it up at an none optimal time. It may be best to let objects owned by lua live the length of the lua object instead. At least until a better option is found. I dont want to resort to manual memory management really. Ill have a PR shortly.

waleed177 commented 1 year ago

Confirmed working on my end! Thank you very much! :D