godot: Editor crashes when clicking on empty area in 2D scene (GCC 6)
Hi!
Operating system or device - Godot version: Arch Linux, GCC 6.1.1, x86-64 build, Godot 2.0.3
Issue description (what happened, and what was expected): Editor crashes when clicking on empty area in 2D scene.
Steps to reproduce:
- compile Godot “target=release_debug” using GCC 6 (any optimization level other than -O0),
- run the editor,
- switch to 2D scene,
- add root Node,
- click on empty area.
Current behavior: crash Expected behavior: doesn’t crash
I’ve noticed that Godot calls a method cast_to()
when the pointer points to 0x0
. This method doesn’t use member variables, but anyway it crashes on GCC 6. I think calling a method when pointer is 0x0
especially for casting from this
is not a good idea, because the behavior is undefined - in most cases it works properly, but - as You can see - not always (e.g. GCC 6 or probably other special cases).
Godot crashes somewhere inside C++ library __cxxabiv1::__dynamic_cast
(the rdi
register - which is first function argument treated as a pointer - is 0x0, so it must crash):
50 [1] in /build/gcc-multilib/src/gcc/libstdc++-v3/libsupc++/dyncast.cc
0x7f42c08e89d0 <+0x0020> 48 8b 07 mov rax,QWORD PTR [rdi]
When compiling with -O0
optimization the it works fine - it doesn’t call the __cxxabiv1::__dynamic_cast
function and it returns NULL
immediately. The __cxxabiv1::__dynamic_cast
function mustn’t be called with NULL
argument.
It is difficult to debug it on -Og
level due to optimizations (can’t debug on -O0
, because it works properly), but when I reading the assembly code, it looks for me like GCC 6 does an optimization: it doesn’t check the this
argument before calling the dynamic_cast
, because it expects that this
will never be NULL
.
This patch fixes the issue:
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index 0213dbd..7f045e9 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1492,7 +1492,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
while ((n && n != scene && n->get_owner() != scene) || (n && !n->is_type("CanvasItem"))) {
n = n->get_parent();
};
- c = n->cast_to<CanvasItem>();
+ c = n ? n->cast_to<CanvasItem>() : 0;
#if 0
if ( b.pressed ) box_selection_start( click );
#endif
The alternative is to check whether this
isn’t NULL
before calling the dynamic_cast
inside Object::cast_to<>()
method.
Maybe some other crashes caused by GCC 6 are also related to this?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 65 (61 by maintainers)
Commits related to this issue
- Fix: Should never call cast_to on a NULL object - There may be other places I'm missing where cast should be checked. But the main spot for bug #4673 is taken care of at: scene/main/viewport.cpp:2... — committed to Razzlegames/godot by Razzlegames 8 years ago
- Fix: Should never call cast_to on a NULL object - There may be other places I'm missing where cast should be checked. But the main spot for bug #4673 is taken care of at: scene/main/viewport.cpp:2... — committed to Razzlegames/godot by Razzlegames 8 years ago
- Attempt to resolve #4673 (cherry picked from commit 1939e83a653b3263eeac820a9e36d751a314068b) — committed to godotengine/godot by reduz 7 years ago
will fix these issues in 3.0, when we change all the memory allocation code
@jedStevens you can do a workaround:
target=release_debug use_llvm=yes
to get optimized and stable code (sudo pacman -S clang
).