godot_luaAPI icon indicating copy to clipboard operation
godot_luaAPI copied to clipboard

Bug Report: Stack Overflow When Calling Functions Enough Times

Open SumianVoice opened this issue 1 year ago • 5 comments

When calling a Lua method from gdscript some number of times, Lua will return a stack overflow error.

To Reproduce Run this code for ~10s.

extends Node2D
var api : LuaAPI = LuaAPI.new()

var label : RichTextLabel

func _ready():
	label = RichTextLabel.new()
	label.name = "label"
	self.add_child(label)
	label.global_position = Vector2(100, 100)
	label.size = Vector2(100, 100)
	
	api.bind_libraries(["base"])
	api.do_string("""
	local i = 0
	function do_something(delta)
		i = i + 1
		return i
	end
	""")

func _process(delta):
	var throw_errors = false
	if api.function_exists("do_something"):
		for i in range(1, 1000):
			var val = api.call_function("do_something", [delta])
			if (val is LuaError):
				if throw_errors:
					assert(false, "ERROR %d: %s" % [val.type, val.message])
				else:
					return
			label.text = str(val)

Stack overflow might be happening at some specific number of calls. image

When forcing it to call the same function 100 times per frame it still crashes on the 999996th call. When removing the assert line, it crashes at 1000190 in current version and 1000191 in the AssetLib, Godot 4.1.1 version, unknown why it can get higher than the above.

Expected behavior Lua functions should be able to be called infinite times without a stack overflow.

Environment:

  • OS: Linux Mint 20.1 Cinnamon
  • Godot version: v4.2.2.stable.official [15073afe3] and v4.1.1.stable.official [bd6af8e0e]
  • Module version: v2.1-beta11 - gdextension-LuaJIT.zip

Additional context Also had the same issue from Godot 4.1.1 with the AssetLib version.

Could also be possible I'm just using things wrong.

SumianVoice avatar Apr 24 '24 04:04 SumianVoice

Note if you call two functions, the effect is additive. Calling any functions, an accumulative total of 1000191 times will crash, even if those calls are spread across 100 functions.

Also any call to do_string for example, any call at all seems to iterate this value until it overflows, and all calls to the api count the same, no matter how much code is executed.

SumianVoice avatar Apr 24 '24 04:04 SumianVoice

Is this still reproducible in the latest build?

radiantgurl avatar May 22 '24 20:05 radiantgurl

Latest release yes, latest version of main branch, likely but I don't know since I can't build it. If you use that code I posted but put the do_string call in a loop like for i in 1000, then you'll find out very quickly too.

SumianVoice avatar May 22 '24 22:05 SumianVoice

To verify: api.function_exists api.call_function

radiantgurl avatar May 24 '24 09:05 radiantgurl

Ah oops yep.. The whole process call can be looped yes.

SumianVoice avatar May 24 '24 23:05 SumianVoice