Open badsectoracula opened 3 days ago
Crashes due to error in manifold::UnionFind.
Likely regression from https://github.com/godotengine/godot/pull/94321 @fire
Investigating
Can you help me get a full stack trace for a manifold upstream report? @elalish @smix8
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!manifold::UnionFind<int,unsigned char>::find(int x) Line 146
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/././././utils.h(146)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!manifold::UnionFind<int,unsigned char>::unionXY(int x, int y) Line 158
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/././././utils.h(158)
godot.windows.editor.double.x86_64.llvm.exe!`anonymous namespace'::GetLabels(std::__1::vector<int,std::__1::allocator<int>> & components, const manifold::Vec<std::__1::pair<int,int>> & edges, int numNodes) Line 190
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/impl.cpp(190)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!`anonymous namespace'::DedupePropVerts(manifold::Vec<linalg::vec<int,3>> & triProp, const manifold::Vec<std::__1::pair<int,int>> & vert2vert) Line 200
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/impl.cpp(200)
godot.windows.editor.double.x86_64.llvm.exe!manifold::Manifold::Impl::CreateFaces() Line 358
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/impl.cpp(358)
godot.windows.editor.double.x86_64.llvm.exe!manifold::Manifold::Impl::Impl<double,unsigned long long>(const manifold::MeshGLP<double,unsigned long long> & meshGL) Line 217
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/././impl.h(217)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!std::__1::allocator<manifold::Manifold::Impl>::construct(manifold::Manifold::Impl * __p, const manifold::MeshGLP<double,unsigned long long> & __args) Line 165
at /__w/world-godot/world-godot/mingw/x86_64-w64-mingw32/include/c++/v1/__memory/allocator.h(165)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!std::__1::allocator_traits<std::__1::allocator<manifold::Manifold::Impl>>::construct(std::__1::allocator<manifold::Manifold::Impl> & __p, manifold::Manifold::Impl * __args, const manifold::MeshGLP<double,unsigned long long> &) Line 319
at /__w/world-godot/world-godot/mingw/x86_64-w64-mingw32/include/c++/v1/__memory/allocator_traits.h(319)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!std::__1::__shared_ptr_emplace<manifold::Manifold::Impl,std::__1::allocator<manifold::Manifold::Impl>>::__shared_ptr_emplace(std::__1::allocator<manifold::Manifold::Impl> __args, const manifold::MeshGLP<double,unsigned long long> &) Line 264
at /__w/world-godot/world-godot/mingw/x86_64-w64-mingw32/include/c++/v1/__memory/shared_ptr.h(264)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!std::__1::allocate_shared(const std::__1::allocator<manifold::Manifold::Impl> & __args, const manifold::MeshGLP<double,unsigned long long> &) Line 843
at /__w/world-godot/world-godot/mingw/x86_64-w64-mingw32/include/c++/v1/__memory/shared_ptr.h(843)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!std::__1::make_shared(const manifold::MeshGLP<double,unsigned long long> & __args) Line 851
at /__w/world-godot/world-godot/mingw/x86_64-w64-mingw32/include/c++/v1/__memory/shared_ptr.h(851)
godot.windows.editor.double.x86_64.llvm.exe!manifold::Manifold::Manifold(const manifold::MeshGLP<double,unsigned long long> & meshGL64) Line 289
at /__w/world-godot/world-godot/godot/thirdparty/manifold/src/manifold.cpp(289)
godot.windows.editor.double.x86_64.llvm.exe!_pack_manifold(const CSGBrush * const p_mesh_merge, manifold::Manifold & r_manifold, HashMap<int,Ref<Material>,HashMapHasherDefault,HashMapComparatorDefault<int>,DefaultTypedAllocator<HashMapElement<int,Ref<Material>>>> & p_mesh_materials, float p_snap) Line 295
at /__w/world-godot/world-godot/godot/modules/csg/csg_shape.cpp(295)
godot.windows.editor.double.x86_64.llvm.exe!CSGShape3D::_get_brush() Line 333
at /__w/world-godot/world-godot/godot/modules/csg/csg_shape.cpp(333)
godot.windows.editor.double.x86_64.llvm.exe!CSGShape3D::_update_shape() Line 444
at /__w/world-godot/world-godot/godot/modules/csg/csg_shape.cpp(444)
godot.windows.editor.double.x86_64.llvm.exe!CallQueue::_call_function(const Callable & p_callable, const Variant * p_args, int p_argcount, bool p_show_error) Line 220
at /__w/world-godot/world-godot/godot/core/object/message_queue.cpp(220)
godot.windows.editor.double.x86_64.llvm.exe!CallQueue::flush() Line 268
at /__w/world-godot/world-godot/godot/core/object/message_queue.cpp(268)
godot.windows.editor.double.x86_64.llvm.exe!SceneTree::physics_process(double p_time) Line 548
at /__w/world-godot/world-godot/godot/scene/main/scene_tree.cpp(548)
godot.windows.editor.double.x86_64.llvm.exe!Main::iteration() Line 4383
at /__w/world-godot/world-godot/godot/main/main.cpp(4383)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!ProgressDialog::_update_ui() Line 133
at /__w/world-godot/world-godot/godot/editor/progress_dialog.cpp(133)
godot.windows.editor.double.x86_64.llvm.exe!ProgressDialog::task_step(const String & p_task, const String & p_state, int p_step, bool p_force_redraw) Line 223
at /__w/world-godot/world-godot/godot/editor/progress_dialog.cpp(223)
godot.windows.editor.double.x86_64.llvm.exe!EditorNode::progress_task_step(const String & p_task, const String & p_state, int p_step, bool p_force_refresh) Line 4917
at /__w/world-godot/world-godot/godot/editor/editor_node.cpp(4917)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!EditorProgress::step(const String & p_state, int p_step, bool p_force_refresh) Line 184
at /__w/world-godot/world-godot/godot/editor/editor_node.cpp(184)
godot.windows.editor.double.x86_64.llvm.exe!EditorNode::_load_editor_layout() Line 5290
at /__w/world-godot/world-godot/godot/editor/editor_node.cpp(5290)
godot.windows.editor.double.x86_64.llvm.exe!EditorNode::_sources_changed(bool) Line 1139
at /__w/world-godot/world-godot/godot/editor/editor_node.cpp(1139)
godot.windows.editor.double.x86_64.llvm.exe!Object::emit_signalp(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 1200
at /__w/world-godot/world-godot/godot/core/object/object.cpp(1200)
godot.windows.editor.double.x86_64.llvm.exe!Object::emit_signal<bool>(const StringName & p_name, bool p_args) Line 922
at /__w/world-godot/world-godot/godot/./core/object/object.h(922)
godot.windows.editor.double.x86_64.llvm.exe!EditorFileSystem::_notification(int p_what) Line 1701
at /__w/world-godot/world-godot/godot/editor/editor_file_system.cpp(1701)
godot.windows.editor.double.x86_64.llvm.exe!Object::notification(int p_notification, bool p_reversed) Line 878
at /__w/world-godot/world-godot/godot/core/object/object.cpp(878)
godot.windows.editor.double.x86_64.llvm.exe!SceneTree::_process_group(SceneTree::ProcessGroup * p_group, bool p_physics) Line 1061
at /__w/world-godot/world-godot/godot/scene/main/scene_tree.cpp(1061)
godot.windows.editor.double.x86_64.llvm.exe!SceneTree::_process(bool p_physics) Line 1127
at /__w/world-godot/world-godot/godot/scene/main/scene_tree.cpp(1127)
godot.windows.editor.double.x86_64.llvm.exe!SceneTree::process(double p_time) Line 590
at /__w/world-godot/world-godot/godot/scene/main/scene_tree.cpp(590)
godot.windows.editor.double.x86_64.llvm.exe!Main::iteration() Line 4427
at /__w/world-godot/world-godot/godot/main/main.cpp(4427)
godot.windows.editor.double.x86_64.llvm.exe!OS_Windows::run() Line 1991
at /__w/world-godot/world-godot/godot/platform/windows/os_windows.cpp(1991)
godot.windows.editor.double.x86_64.llvm.exe!widechar_main(int argc, wchar_t * * argv) Line 184
at /__w/world-godot/world-godot/godot/platform/windows/godot_windows.cpp(184)
[Inline Frame] godot.windows.editor.double.x86_64.llvm.exe!_main() Line 206
at /__w/world-godot/world-godot/godot/platform/windows/godot_windows.cpp(206)
godot.windows.editor.double.x86_64.llvm.exe!main(int argc, char * * argv) Line 225
at /__w/world-godot/world-godot/godot/platform/windows/godot_windows.cpp(225)
[External Code]
Mine is almost the same:
[1] /lib64/libc.so.6(+0x41580) [0x7f9758441580] (??:0)
[2] manifold::UnionFind<int, unsigned char>::find(int) (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/././utils.h:147 (discriminator 2))
[3] manifold::UnionFind<int, unsigned char>::unionXY(int, int) (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/././utils.h:158 (discriminator 1))
[4] /mnt/haus/badsector/Code/godot/bin/godot.linuxbsd.editor.dev.x86_64() [0x72c233f] (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/impl.cpp:190)
[5] /mnt/haus/badsector/Code/godot/bin/godot.linuxbsd.editor.dev.x86_64() [0x72c23ce] (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/impl.cpp:200 (discriminator 1))
[6] manifold::Manifold::Impl::CreateFaces() (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/impl.cpp:362)
[7] manifold::Manifold::Impl::Impl<double, unsigned long>(manifold::MeshGLP<double, unsigned long> const&) (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/./impl.h:217)
[8] void std::_Construct<manifold::Manifold::Impl, manifold::MeshGLP<double, unsigned long> const&>(manifold::Manifold::Impl*, manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/stl_construct.h:120)
[9] std::_Sp_counted_ptr_inplace<manifold::Manifold::Impl, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<manifold::MeshGLP<double, unsigned long> const&>(std::allocator<void>, manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/alloc_traits.h:694)
[10] std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<manifold::Manifold::Impl, std::allocator<void>, manifold::MeshGLP<double, unsigned long> const&>(manifold::Manifold::Impl*&, std::_Sp_alloc_shared_tag<std::allocator<void> >, manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/shared_ptr_base.h:969 (discriminator 3))
[11] std::__shared_ptr<manifold::Manifold::Impl, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<void>, manifold::MeshGLP<double, unsigned long> const&>(std::_Sp_alloc_shared_tag<std::allocator<void> >, manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/shared_ptr_base.h:1714)
[12] std::shared_ptr<manifold::Manifold::Impl>::shared_ptr<std::allocator<void>, manifold::MeshGLP<double, unsigned long> const&>(std::_Sp_alloc_shared_tag<std::allocator<void> >, manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/shared_ptr.h:464)
[13] std::shared_ptr<std::enable_if<!std::is_array<manifold::Manifold::Impl>::value, manifold::Manifold::Impl>::type> std::make_shared<manifold::Manifold::Impl, manifold::MeshGLP<double, unsigned long> const&>(manifold::MeshGLP<double, unsigned long> const&) (/usr/include/c++/14/bits/shared_ptr.h:1009)
[14] manifold::Manifold::Manifold(manifold::MeshGLP<double, unsigned long> const&) (/mnt/haus/badsector/Code/godot/thirdparty/manifold/src/manifold.cpp:289 (discriminator 1))
[15] /mnt/haus/badsector/Code/godot/bin/godot.linuxbsd.editor.dev.x86_64() [0x734156a] (/mnt/haus/badsector/Code/godot/modules/csg/csg_shape.cpp:296 (discriminator 1))
[16] CSGShape3D::_get_brush() (/mnt/haus/badsector/Code/godot/modules/csg/csg_shape.cpp:334)
[17] CSGShape3D::_update_shape() (/mnt/haus/badsector/Code/godot/modules/csg/csg_shape.cpp:444)
[18] void call_with_variant_args_helper<CSGShape3D>(CSGShape3D*, void (CSGShape3D::*)(), Variant const**, Callable::CallError&, IndexSequence<>) (/mnt/haus/badsector/Code/godot/./core/variant/binder_common.h:309)
[19] void call_with_variant_args<CSGShape3D>(CSGShape3D*, void (CSGShape3D::*)(), Variant const**, int, Callable::CallError&) (/mnt/haus/badsector/Code/godot/./core/variant/binder_common.h:419)
[20] CallableCustomMethodPointer<CSGShape3D, void>::call(Variant const**, int, Variant&, Callable::CallError&) const (/mnt/haus/badsector/Code/godot/./core/object/callable_method_pointer.h:111)
[21] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/mnt/haus/badsector/Code/godot/core/variant/callable.cpp:57)
[22] CallQueue::_call_function(Callable const&, Variant const*, int, bool) (/mnt/haus/badsector/Code/godot/core/object/message_queue.cpp:221)
[23] CallQueue::flush() (/mnt/haus/badsector/Code/godot/core/object/message_queue.cpp:270)
[24] SceneTree::physics_process(double) (/mnt/haus/badsector/Code/godot/scene/main/scene_tree.cpp:548)
[25] Main::iteration() (/mnt/haus/badsector/Code/godot/main/main.cpp:4383 (discriminator 3))
[26] OS_LinuxBSD::run() (/mnt/haus/badsector/Code/godot/platform/linuxbsd/os_linuxbsd.cpp:962 (discriminator 1))
[27] /mnt/haus/badsector/Code/godot/bin/godot.linuxbsd.editor.dev.x86_64(main+0x14b) [0x67859c1] (/mnt/haus/badsector/Code/godot/platform/linuxbsd/godot_linuxbsd.cpp:85)
[28] /lib64/libc.so.6(+0x2a2ae) [0x7f975842a2ae] (??:0)
[29] /lib64/libc.so.6(__libc_start_main+0x8b) [0x7f975842a379] (??:0)
[30] /mnt/haus/badsector/Code/godot/bin/godot.linuxbsd.editor.dev.x86_64(_start+0x25) [0x67857a5] (/home/abuild/rpmbuild/BUILD/glibc-2.40/csu/../sysdeps/x86_64/start.S:117)
Waiting for https://github.com/elalish/manifold/pull/1040 to be completed, but the cause of the crash was identified as:
I'm replacing our CreateFaces algorithm. Our previous was based on connected components, but in the case of e.g. a high-res sphere, it would connect everything into one big face. So then we added an algorithm to check global tolerance of each face after the fact, and if that failed, it would just throw out all the faces and say each triangle was individual.
To be clear, I have not at all identified (or even reproduced) a crash yet.
Maybe unrelated but I also noticed crashes in master when dragging the finicky CSG editor handles e.g. CSGBox3D size handles in the editor.
Just spawn a single CSGBox3D node and try to drag the editor handles for its size adjustment. If one axis lag-jumps to e.g. a zero size it crashes the editor with a manifold crash.
I dont know what data we are feeding to the poor manifold but it does not seem to like such non-geometry input so such input should likely be already skipped on the editor side.
I want to do it at least if the mesh is not manifold, avoid crashing, and return the empty mesh.
I dont know what data we are feeding to the poor manifold but it does not seem to like such non-geometry input so such input should likely be already skipped on the editor side.
Is there a easy to code way to verify non manifold without constructing a Manifold:manifold?
Manifold should already be robust to this: if you try to construct a manifold with non-manifold input, it returns an empty manifold with the status set to the appropriate error condition. If you do further operations using that empty result, that error will propagate through those results as well. It certainly shouldn't crash. You can check the error status after each construction to find the input mesh that has a problem.
The current pull request code merely patches over the crash.
We will need an investigation to see why this polygon cannot be spun.
Does Spin mean "create an object of revolution"? If so, have you tried Manifold's Revolve
function?
I'm starting to get some results with Manifold's Revolve.
Spinning is most likely a red herring as a crash inside manifold can happen by creating a CSGBox3D
and dragging one of its handles to make it zero sized (e.g. i grabbed the topmost handle and dragged it down and the editor crashed).
I'll also check the PR to see if i can get it to crash.
Tested versions
Reproducible in: 893bbdfde8ad1f94fb4e6db246ff7075569396ea Not reproducible in: d09d82d433b03bb3773fd2a8cc8d6ccc2f8739ce
I bisected the crash and it seems to be introduced in fda444bb01defafc84016f00dcbf815be06d7143 from https://github.com/godotengine/godot/pull/94321.
System information
Godot v4.4.dev (893bbdfde) - openSUSE Tumbleweed 20241022 on X11 - X11 display driver, Multi-window, 1 monitor - OpenGL 3 (Compatibility) - AMD Radeon RX 5700 XT (radeonsi, navi10, LLVM 18.1.8, DRM 3.59, 6.11.3-2-default) - AMD Ryzen 7 3700X 8-Core Processor (16 threads)
Issue description
A CSGPolygon3D in the scene with the mode set to Spin will crash the editor.
Steps to reproduce
The editor will crash at step 4.
Alternatively try to open the MRP.
Minimal reproduction project (MRP)
MRP: this-csg-crashes-the-editor.zip