Closed
Description
Godot version
4.x latest 0308422
System information
All
Issue description
Editor tab with TileMap
can crash on closing the tab.
1 TileMapEditorPlugin::edit tiles_editor_plugin.cpp 351 0x55555d13b2e4
2 EditorNode::_plugin_over_edit editor_node.cpp 890 0x55555bf70ce7
3 EditorNode::hide_unused_editors editor_node.cpp 2242 0x55555bf88b6c
4 SceneTreeDock::_push_item scene_tree_dock.cpp 1488 0x55555c3386e2
5 SceneTreeDock::_selection_changed scene_tree_dock.cpp 2276 0x55555c3582a1
6 call_with_variant_args_helper<SceneTreeDock>(SceneTreeDock *, void (SceneTreeDock:: *)(), Variant const * *, Callable::CallError&, IndexSequence<>) binder_common.h 303 0x55555c42af09
7 call_with_variant_args<SceneTreeDock> binder_common.h 417 0x55555c42ae79
8 CallableCustomMethodPointer<SceneTreeDock>::call callable_method_pointer.h 104 0x55555c42ad64
9 Callable::callp callable.cpp 50 0x55555f921a7a
10 Object::emit_signalp object.cpp 1072 0x55555fcff623
11 Object::emit_signal<>(StringName const&) object.h 891 0x55555b28b203
12 EditorSelection::_emit_change editor_data.cpp 1292 0x55555bd07649
13 call_with_variant_args_helper<__UnexistingClass>(__UnexistingClass *, void (__UnexistingClass:: *)(), Variant const * *, Callable::CallError&, IndexSequence<>) binder_common.h 303 0x55555a859f19
14 call_with_variant_args_dv<__UnexistingClass> binder_common.h 450 0x55555a859e7c
15 MethodBindT<>::call(Object *, Variant const * *, int, Callable::CallError&) const method_bind.h 331 0x55555a859c46
16 Object::callp object.cpp 741 0x55555fcfcdcf
17 Callable::callp callable.cpp 62 0x55555f921e77
18 CallQueue::_call_function message_queue.cpp 219 0x55555fcf7640
19 CallQueue::flush message_queue.cpp 324 0x55555fcf7eca
20 SceneTree::physics_process scene_tree.cpp 471 0x55555d2b1935
... <More>
It's crashing here:
void TileMapEditorPlugin::edit(Object *p_object) {
if (tile_map) {
tile_map->disconnect("changed", callable_mp(this, &TileMapEditorPlugin::_tile_map_changed));
}
Where p_object
is NULL, so it looks like it's trying to wipe the old tilemap from the plugin, but it is still accessing the old deleted tilemap.
There's no need to call this on a deleted tilemap as the destructor already does this:
TileMap::~TileMap() {
if (tile_set.is_valid()) {
tile_set->disconnect_changed(callable_mp(this, &TileMap::_tile_set_changed));
}
Steps to reproduce
Use MRP from #80088.
- Open scene
- Open
TileSet
dropdown in theTileMap
inspector - Close tab
- CRASH
Minimal reproduction project
See above.
Discussion
A number of ways of fixing, e.g.:
- Check validity by storing
ObjectID
and checking valid before use - Signal to let tilemap editor know has been destroyed
- Use reference instead of raw pointer, so the object is preserved until
edit()
is called and it is assigned to something else.