Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lots of Unreferenced static string to 0: errors when closing a scene #20

Open
takethebait opened this issue Sep 2, 2024 · 9 comments · May be fixed by #23
Open

Lots of Unreferenced static string to 0: errors when closing a scene #20

takethebait opened this issue Sep 2, 2024 · 9 comments · May be fixed by #23

Comments

@takethebait
Copy link

Godot version

Godot v4.4.dev (7c383767a)

Godot .NET packages version

master (9cb7bec)

System information

Godot v4.4.dev (7c383767a) - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 32.0.15.6094) - AMD Ryzen 9 3900X 12-Core Processor (24 Threads)

.NET information

.NET SDK: Version: 8.0.400 Commit: 36fe6dda56 Workload version: 8.0.400-manifests.56cd0383 MSBuild version: 17.11.3+0c8610977

Issue description

When closing a project which has an instance of a class, that's defined in a C# GDExtension, a lot of ERROR: BUG: Unreferenced static string to 0: {_process | _enter_tree | _ready | _input | ...} messages are printed in between Disposing tracked instances and Finished disposing tracked instances to the console. When explicitly overriding these methods in GDScript they will no longer be included in that list.

Steps to reproduce

  1. Declare a basic class on the C# side:
[GodotClass]
public partial class SampleNode : Node3D
{

}
  1. Register that class as a runtime class in the ClassDB
  2. Create a node of the type created in step 1 in a scene and attach an empty script written in GDScript that extends this type to it.
  3. Either run the scene and exit it from the editor or export the scene and run the exported version.

When running the scene from the editor, error message are only printed sporadically, sometimes there are none at all and everything seems to work just fine. Exporting the project however should print these errors every time you close the scene.

You can also notice that the amount of error messages become fewer the more methods you override in GDScript. When overriding _ready, _process, _physics_process, _enter_tree, _exit_tree, _unhandled_input, _input, _shortcut_input and _unhhandled_key_input no error messages should remain.

Minimal reproduction project

N/A

@scgm0
Copy link
Contributor

scgm0 commented Sep 3, 2024

Some information I got:

ERROR: BUG: Unreferenced static string to 0: _process
   at: unref (core/string/string_name.cpp:120)
Process terminated. Assertion failed.
   at System.Diagnostics.DebugProvider.Fail(String, String) + 0x49
   at System.Diagnostics.Debug.Fail(String, String) + 0x50
   at System.Diagnostics.Debug.Assert(Boolean, String, String) + 0x2c
   at System.Diagnostics.Debug.Assert(Boolean) + 0x27
   at Godot.Bridge.MethodBindInvoker.GetInstanceObject(Void*) + 0x6b
   at Godot.Bridge.MethodBindInvoker.CallVirtualWithPtrArgs(Void*, Void**, Void*) + 0x33
   at Godot.Bridge.ClassDB.CallVirtualMethod_Native(Void*, NativeGodotStringName*, Void*, Void**, Void*) + 0x237

Correction: C# exception has nothing to do with Unreferenced static string to 0, but again, this can be solved by mounting the gds script.
Correction again: They are related. I also found a solution, but it feels a bit strange. Let me create a PR first.

@scgm0
Copy link
Contributor

scgm0 commented Sep 3, 2024

@takethebait can you try #21?

@takethebait
Copy link
Author

@scgm0 tested the changes but unfortunately the error persists at least on my end and the behaviour has not changed.

@scgm0
Copy link
Contributor

scgm0 commented Sep 3, 2024

@scgm0 tested the changes but unfortunately the error persists at least on my end and the behaviour has not changed.

Same here, found it just delayed the problem, waiting for Raul. . .

@takethebait
Copy link
Author

takethebait commented Sep 3, 2024

I went ahead and tried to debug the disposable tracking (do note that I'm not very familiar with the code yet):

I'm noticing that a weak reference is registered for every _process and _physics_process as well as all the other events. Won't this result in something like an OutOfMemoryException at some point since instances only seem to be deregistered on shutdown?

The Unreferenced static string errors are thrown when the disposable tracker attempts to unregister one of these _process etc. string names.

My log looks something like this during the registration:
image

and like this during deregistration:
image

Edit:
I also found that names such as "script", "Node3D", "OS", in this case "SampleNode" unregister just fine, it's only the function names.

Edit 2:
Correct me if I'm wrong but shouldn't these function names be registered as static StringNames and therefore not even be tracked by the DisposeTracker? I now believe this to be incorrect.

The constant registration happens in CallVirtualMethod_Native

I don't know if this is of any help but I found this interesting.

@takethebait takethebait changed the title Lot's of Unreferenced static string to 0: errors when closing a scene Lots of Unreferenced static string to 0: errors when closing a scene Sep 3, 2024
@scgm0
Copy link
Contributor

scgm0 commented Sep 3, 2024

I found that when the problem occurs, the Dispose method of the custom node is called.
image
So I manually retained a static reference and ran it again for 5 minutes, and the problem seemed to disappear.
image

@scgm0
Copy link
Contributor

scgm0 commented Sep 4, 2024

It is found that a StringName like _physics_process is static when it is first instantiated, but then a lot of non-static StringName instances are created.
图片
图片
图片

@scgm0 scgm0 linked a pull request Sep 4, 2024 that will close this issue
@raulsntos
Copy link
Owner

Thanks to you both for looking into this issue. Correct me if I'm wrong but it looks like this issue only happens with the StringName instances from virtual method names. If so, it looks like it may be because we're taking ownership of those StringName instances here:

StringName methodNameStr = StringName.CreateTakingOwnership(*name);

Maybe we should not be taking ownership of those StringName instances. Instead we could try copying it into a new StringName instance.

@takethebait
Copy link
Author

I'm not 100% that its only virtual methods as every time I close down the editor while having a project with a NET GDExtension loaded I also get an error for the string MultiplayerAPI. This only happens in the editor however, not in an exported project.

Haven't looked into that one yet though, I'll try to see where it comes from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants