bitwes / Gut

Godot Unit Test. Unit testing tool for Godot Game Engine.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Doubles: Can't free a reference

Scrawach opened this issue · comments

Versions

  • Godot: 4.2.2
  • GUT: 9.3.0
  • OS: Linux

The Bug

When double is created, a check is made to see if the type is native or not. Depending on this, the decision to free is made.

Source code

func _init(script_or_inst, inner_class=null):
var to_load = script_or_inst
if(GutUtils.is_native_class(to_load)):
_resource = to_load
_is_native = true
var inst = to_load.new()
_native_class_name = inst.get_class()
_native_methods = inst.get_method_list()
inst.free()
else:

However, it is not valid for all native types in gdscript to call the free() method. For example, is StreamPeerTCP, which inherits from RefCounted (and many others). When trying to free such an instance, Godot will throw an error:

ERROR: Can't 'free' a reference.
   at: callp (core/object/object.cpp:733)

There is one more thing that needs attention here (for script_parser.gd): creation of custom types inherited from Object. When creating double for non-native types, inherited from Object, after load, free() is not called anywhere, which may lead to memory leaks.

Possible Fixes

Check type before free. For example,

Solution
if(GutUtils.is_native_class(to_load)):
	...
	
	if not inst is RefCounted:
		inst.free()
else:
	...

I can do a PR with fixes and tests if it looks good.

Steps To Reproduce

  1. Create test_free_reference.gd:
extends GutTest

func test_cant_free_reference_when_double() -> void:
	double(StreamPeerTCP).new()
	pass_test("Test passed.")
  1. Run tests.
  2. Result:
ERROR: Can't 'free' a reference.
   at: callp (core/object/object.cpp:733)

Good find. Did you discover this after upgrading to 9.3 or is it just coincidental that you found this shortly after the release of 9.3?

Just a coincidence. So I can't say if this bug was present before 9.3. Another coincidence is that I started using the framework exactly with 9.3 :)

Well, you my friend, have impeccable timing. It just so happens that I had made a very late change to this code for 9.3. It turns out this was an existing issue, but it would have appeared with different timing, and I could see it possibly not showing up in some weird cases.

Thanks for offering to fix it. In my scramble to fix, what I thought was for sure a new bug, I missed you saying that. Your suggestion is exactly how I fixed it. I'm going to merge in the fix. I will wait a bit to see if any more bugs show up, then I'll put this in a point release.