(C++ module) Memory unrefs problems at cleanup after editor closing

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By desperate-coder

Hi fellow Godot-ers,

wanted to create a custom gui-node via a C++ module, which works fine until i close the editor and the console logged out some memory-related cleanup-problems.
The node works fine and does what it should while in use in the editor though.
Just seems my current usage causes memory disruptions, which i would like to fix to maintain a cleaner code base.

In the engine sources itself and looking around web yield no results to my question, so i hope i might find help here.
Would be very kind if someone can hint me where the error is or how i have to configure my node right.

To my custom node:
I try to set up a default ShaderMaterial, with default shader code and a black ImageTexture via code, and set the worked out Resources into the final node.
This i do in order to encapsulate some shader processing logic that i wish to standardize.

As said above, In the editor, the node can be used without problems, just the closing appears to have problems.
I commented out several blocks for debug-purposes multiple times, tried to change the memory referencing (from Ref to * for example), but there are several of these memory errors appearing nonetheless (not just the Shader-object like shown at the end).
Only if i dont set the produced “default members” into the final node, then there appears to be no problem at all (albeit the node is useless then as well…)

Here the relevant source-code:

The constructor
(said problems occur in “this->build_default_transition_mask();” and “set_material ( transition_material );”.
If these are commented out, no memory issues appear)

VDTransitionShaderMask::VDTransitionShaderMask()
{
     Color def_color = Color ( 0, 0, 0 );
     set_frame_color ( def_color );
     set_mouse_filter ( MouseFilter::MOUSE_FILTER_PASS );
     set_anchor ( MARGIN_RIGHT, 1.0 );
     set_anchor ( MARGIN_BOTTOM, 1.0 );
     this->build_default_transition_mask();
     Ref<Shader> transition_shader;
     transition_shader.instance();
     transition_shader->set_code ( VDTransitionShaderMask::default_shader_code );
     transition_material.instance();
     transition_material->set_shader ( transition_shader );
     set_material ( transition_material );
     set_transition_time ( transition_time );
}

Building the default texture

Ref<Texture> VDTransitionShaderMask::build_default_transition_mask()
{
     Color color = Color ( 0, 0, 0 );
     Ref<Image> image;
	 image.instance();
     image->create ( 1, 1, false, Image::FORMAT_RF );
     image->lock();
     image->set_pixel ( 0,0, color );
     Ref<ImageTexture> image_texture;
	 image_texture.instance();
     image_texture->create_from_image ( image );
     return image_texture;
}

The relevant parts of the header:

class VDTransitionShaderMask : public ColorRect
{
    GDCLASS ( VDTransitionShaderMask, ColorRect );

    Ref<Texture> build_default_transition_mask();

protected:
    static void _bind_methods();
    void _notification ( int what );

    Ref<ShaderMaterial> transition_material;
    static const String default_shader_code;

Finally, the output log (censored some information, for privacy protection)

handle_crash: Program crashed with signal 11
Dumping the backtrace. 
[1] /usr/lib/libc.so.6(+0x3d6a0) [0x7f0266e506a0] (??:0)
[2] Shader::~Shader() (.../GodotEngine/scene/resources/shader.cpp:197)
[3] void memdelete<Shader>(Shader*) (.../GodotEngine/./core/os/memory.h:119)
[4] Ref<Shader>::unref() (.../GodotEngine/./core/reference.h:281)
[5] Ref<Shader>::~Ref() (.../GodotEngine/./core/reference.h:296)
[6] ShaderMaterial::~ShaderMaterial() (.../GodotEngine/scene/resources/material.cpp:288)
[7] void memdelete<Reference>(Reference*) (.../GodotEngine/./core/os/memory.h:119)
[8] Ref<Reference>::unref() (.../GodotEngine/./core/reference.h:281)
[9] RefPtr::unref() (.../GodotEngine/core/ref_ptr.cpp:91)
[10] Variant::clear() (.../GodotEngine/core/variant.cpp:1135)
[11] Variant::~Variant() (.../GodotEngine/./core/variant.h:435)
[12] HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Pair::~Pair() (.../GodotEngine/./core/hash_map.h:61)
[13] HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element::~Element() (.../GodotEngine/./core/hash_map.h:73)
[14] void memdelete<HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element>(HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element*) (.../GodotEngine/./core/os/memory.h:119)
[15] HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::clear() (.../GodotEngine/./core/hash_map.h:533)
[16] HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::~HashMap() (.../GodotEngine/./core/hash_map.h:599)
[17] HashMap<StringName, HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Pair::~Pair() (.../GodotEngine/./core/hash_map.h:61)
[18] HashMap<StringName, HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element::~Element() (.../GodotEngine/./core/hash_map.h:73)
[19] void memdelete<HashMap<StringName, HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element>(HashMap<StringName, HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::Element*) (.../GodotEngine/./core/os/memory.h:119)
[20] HashMap<StringName, HashMap<StringName, Variant, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>, HashMapHasherDefault, HashMapComparatorDefault<StringName>, (unsigned char)3, (unsigned char)8>::clear() (.../GodotEngine/./core/hash_map.h:533)
[21] ClassDB::cleanup_defaults() (.../GodotEngine/core/class_db.cpp:1449)
[22] unregister_core_types() (.../GodotEngine/core/register_core_types.cpp:311)
[23] Main::cleanup() (.../GodotEngine/main/main.cpp:2298)
[24] .../GodotEngine/bin/godot.x11.tools.64(main+0x126) [0x146970c] (.../GodotEngine/platform/x11/godot_x11.cpp:59)
[25] /usr/lib/libc.so.6(__libc_start_main+0xf2) [0x7f0266e3b152] (??:0)
[26] .../GodotEngine/bin/godot.x11.tools.64(_start+0x2e) [0x146952e] (??:?)
-- END OF BACKTRACE --

Would be very thankful for any help.
Cheers!