godot: void Godot.Object.Finalize(): FATAL: Condition "!Object::cast_to(p_ptr)" is true
Godot version
Godot Engine v4.0.beta3.mono.official.01ae26d31
System information
Windows11 Vulkan API 1.2.0 - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce GTX 1080
Issue description
error info:
E 0:00:15:0082 void Godot.Object.Finalize(): FATAL: Condition "!Object::cast_to<RefCounted>(p_ptr)" is true.
<C++ 源文件> modules/mono/glue/runtime_interop.cpp:155 @ godotsharp_internal_refcounted_disposed()
<栈追踪> Godot.NativeInterop.NativeFuncs.generated.cs:88 @ void Godot.NativeInterop.NativeFuncs.godotsharp_internal_refcounted_disposed(IntPtr , IntPtr , Godot.NativeInterop.godot_bool )()
Object.base.cs:117 @ void Godot.Object.Dispose(Boolean )()
Object.base.cs:80 @ void Godot.Object.Finalize()()
Hi, my english is poor. I don’t know how to solve this problem, but it is not a problem in version 3.5.1. Looks like a GC problem This error occur about 2 seconds after the EmitSignal function call, Then the program will crash
if (shouldEmitSignal)
{
var inventoryEvent = InventoryEvent.NewAddEvent(inventoryItem);
EmitSignal(SignalName.OnEvent, inventoryEvent);
}
Steps to reproduce
This is my code
if (shouldEmitSignal)
{
var inventoryEvent = InventoryEvent.NewAddEvent(inventoryItem);
EmitSignal(SignalName.OnEvent, inventoryEvent);
}
InventoryEvent
public enum InventoryEventType
{
Unknown,
Add,
Remove
}
public partial class InventoryEvent : Godot.RefCounted
{
public InventoryEventType type;
public InventoryItem inventoryItem;
public InventoryEvent()
{
}
public static InventoryEvent NewAddEvent(InventoryItem inventoryItem)
{
InventoryEvent inventoryEvent = new InventoryEvent();
inventoryEvent.type = InventoryEventType.Add;
inventoryEvent.inventoryItem = inventoryItem;
return inventoryEvent;
}
public static InventoryEvent NewRemoveEvent(InventoryItem inventoryItem)
{
InventoryEvent inventoryEvent = new InventoryEvent();
inventoryEvent.type = InventoryEventType.Remove;
inventoryEvent.inventoryItem = inventoryItem;
return inventoryEvent;
}
}
InventoryItem
public partial class InventoryItem : Godot.RefCounted
{
[JsonProperty]
public string icon;
[JsonProperty]
public Level level;
[JsonProperty]
public InventoryItemType type;
[JsonProperty]
public EquipType equipType;
[JsonProperty]
public QualityType qualityType;
......
Minimal reproduction project
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 18 (7 by maintainers)
@firebelley Thanks! #69971 should solve the issue in your project.
Script.New
returns aVariant
. Here you’re boxing that and then attempting to cast it toBaseDefinition
which is an invalid cast.Variant
has a helper implicit conversion, which is the one you’re using in your first example:(BaseDefinition)csFile.New();
(shorthand for(BaseDefinition)csFile.New().AsGodotObject();
).Ok I was able to reproduce this, MRP here: RefCounted Crash MRP.zip
My use case is somewhat strange, so I’ve replicated the relevant parts of my use case in the MRP. Basically, when a
CSharpScript
is loaded usingGD.Load
and then instantiated, then the error will occur on garbage collect or on game exit depending on how the code is implemented. The error doesn’t appear to be related to signals. This code:Will cause an error immediately upon the next garbage collect. In the MRP I am calling
GC.Collect
after every time this script is instantiated. The expected behavior is that the value ofcsFile.New()
can be cast toBaseDefinition
, sinceTestDefinition
extendsBaseDefintion
:Interestingly, if the cast is applied directly to
csFile.New()
the game will only crash with the error when closing the window:In the MRP you can see that when the above method of instantiating the script is used, then you can call
GetDefinition
onDefinition
and see a print to the console with the correct data. This obviously indicates that the cast was successful.And even more interesting, using the
as
keyword seems to returnnull
after the cast:And to reiterate, the error in both cases is as follows: