Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instancing nodes in thread causes random errors #30700

Closed
orosmatthew opened this issue Jul 19, 2019 · 15 comments
Closed

Instancing nodes in thread causes random errors #30700

orosmatthew opened this issue Jul 19, 2019 · 15 comments

Comments

@orosmatthew
Copy link
Contributor

Godot version:
3.1.1 (Steam Stable)

OS/device including version:
Windows 10 64-bit

Issue description:
I am in the middle of making a simple voxel engine and previously used dictionaries to store block information. However, I wanted to use a list of Block objects and so used load("Block.gd").new() and found that I was getting random crashes that had nothing to do with what I had changed and disappeared when switched back to using dictionaries. I then changed it to instance nodes using load("Block.tscn").instance() however it yielded the same result. This bug has taken me about a month to realize what it was. :(

Steps to reproduce:
Run the project which won't display anything but instance a bunch of nodes on a thread. Sometimes it works fine. If it doesn't crash within 15 seconds, try re-running. It really is pretty random.

Minimal reproduction project:
https://drive.google.com/uc?export=download&id=1juo3WX4UPsXRkiMmM84eVkcyzXlUha0E

@Zylann
Copy link
Contributor

Zylann commented Jul 19, 2019

With threads, load("Block.gd") should not have caused errors. Loading resources should be thread-safe. If it isn't, there is a bug somewhere.

Calling new() on a script which does not extends a node type should also be fine.

For load("Block.tscn").instance() , I'm not sure. The scene tree is definitely NOT thread-safe so don't use add_child() from a thread, really.

Although, I don't remember if instancing nodes without adding them to the tree is safe?

@orosmatthew
Copy link
Contributor Author

orosmatthew commented Jul 19, 2019

I am not using add_child() anywhere. All I am doing is instancing (tried both nodes and scripts) and adding them to a dictionary in an already instanced (in scene tree) node. Could that be a problem? I am technically not adding them to the tree.

@KoBeWi
Copy link
Member

KoBeWi commented Jul 19, 2019

Well, nodes aren't freed automatically, so if you somehow lose the reference, it will result in a leak. Other than that, there shouldn't be other problems.

I also had problems with threads once, also when instancing scenes, which were pretty big. It caused nonsensical errors like this
image
or this
image

I haven't observed this behavior since 3.1 stable. Now it just crashes randomly, especially when using master branch.

@santouits
Copy link
Contributor

Try this

in your game.gd

var thread_chunking = Thread.new()
var count = 0
var thread_started = false

and

func chunk_manager():
	if thread_started: return
	
	if not thread_chunking.is_active() and count<300:
		thread_started = true
		count+=1
		place_chunk(Vector3(0,0,0))

in your chunk.gd

func generate_chunk(a):

	calc_chunk(null)
	game.thread_started = false

	a.call_deferred( 'wait_to_finish' )

@fian46
Copy link

fian46 commented Jul 20, 2019

actually i stumble to this weird phenomena 3 month ago. i just think i am just too dumb to report this as bug maybe i don't know what is reference counting should behave in thread. you don't need scene btw just simple script and extends object, instance it on thread and join the thread to main thread carry the object and use it in main thread, and this null reference thing crash the game even editor.

@KoBeWi
Copy link
Member

KoBeWi commented Aug 26, 2019

Eh, I was going to create a similar issue, but it would be too similar, so commenting here. The project attached in the OP doesn't crash for me. However, I have a project that crashes pretty consistently.
MaximalReproductionProject.zip
Just run the game and it should crash after few seconds or after walking around a bit. If it doesn't, just run again. Also sometimes, totally randomly, an error spam like this happens:
image

I'm just hoping someone with more debugging could pinpoint the issue >_>
The threading happens in Maps/Scripts/MapManager.gd.

Also I'd vote for labelling this issue as High Priority, because I'm having it for months and have no idea what to do about it ;_;

@akien-mga akien-mga added this to the 3.2 milestone Aug 26, 2019
@hodgerti
Copy link

hodgerti commented Aug 31, 2019

EDIT: As noted by @santouits below, this particular issue was fixed at 274bac2783

These bugs are similar to:
This issue: #31753
And this issue: #29364

I am also having the random error that @KoBeWi is having:
Attempt to call function 'XXX' in base 'previously freed instance' on a null instance.
image

It seems to always be called on Children and Grandchildren of my active scene.
Here is a demo of the issue. You'll need to run it multiple times to pop the error:
scuffed_game_crippled.zip

@santouits
Copy link
Contributor

The "Attempt to call function 'XXX' in base 'previously freed instance' on a null instance" issues should have been fixed by this, but I can't run your project because it is not compatible with the master branch.

@akien-mga
Copy link
Member

I ran the project in the OP five times without any crash, so I assume it might have been fixed by #30934.

@KoBeWi's project did not trigger a crash for me, but I get an insane amount of errors when running it on the master branch (mostly physics related). Once I got a freeze of the game in an infinite loop spouting these errors endlessly:

ERROR: _disconnect: Disconnecting nonexistent signal 'changed', slot: 2840:_reload_physics_characteristics.
   At: core/object.cpp:1524.
ERROR: _disconnect: Disconnecting nonexistent signal 'changed', slot: 2840:_reload_physics_characteristics.
   At: core/object.cpp:1524.

I think there are too many bugs in that projects too properly diagnose what could cause the crash in a thread.

I'll close this issue as the bug in OP seems to be fixed. There might still be projects that reproduce weird errors from threads, but it's probably worth opening a dedicated issue for each, unless they are all minimal projects with similar code.

@qarmin
Copy link
Contributor

qarmin commented Dec 26, 2019

I got in KoBeWi reproduction project(https://github.com/godotengine/godot/files/3538958/MaximalReproductionProject.zip) this invalid write(Godot 3.2 Beta 4) in Adress Sanitizer

==18566==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160002cc550 at pc 0x00000e561015 bp 0x7fc1335819d0 sp 0x7fc1335819c0
WRITE of size 4 at 0x6160002cc550 thread T5 (check_loader)
    #0 0xe561014 in Object::Signal::Slot::operator=(Object::Signal::Slot const&) core/object.h:458
    #1 0xe545fe9 in Object::connect(StringName const&, Object*, StringName const&, Vector<Variant> const&, unsigned int) core/object.cpp:1485
    #2 0xb1ea18d in StaticBody2D::set_physics_material_override(Ref<PhysicsMaterial> const&) scene/2d/physics_body_2d.cpp:260
    #3 0xa9501c9 in MethodBind1<Ref<PhysicsMaterial> const&>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:775
    #4 0xe2db298 in ClassDB::set_property(Object*, StringName const&, Variant const&, bool*) core/class_db.cpp:1031
    #5 0xe523e52 in Object::set(StringName const&, Variant const&, bool*) core/object.cpp:422
    #6 0xbf96281 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:253
    #7 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #8 0xbf928b7 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:138
    #9 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #10 0xbff8845 in MethodBind1RC<Node*, PackedScene::GenEditState>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:1333
    #11 0xe533842 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:921
    #12 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #13 0x1a182e9 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1078
    #14 0x18549c3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1173
    #15 0xe5333af in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:900
    #16 0xf0537e1 in _Thread::_start_func(void*) core/bind/core_bind.cpp:2660
    #17 0x4f831d5 in ThreadPosix::thread_callback(void*) drivers/unix/thread_posix.cpp:74
    #18 0x7fc140427668 in start_thread /build/glibc-4WA41p/glibc-2.30/nptl/pthread_create.c:479
    #19 0x7fc13f688322 in clone (/lib/x86_64-linux-gnu/libc.so.6+0x122322)

0x6160002cc550 is located 208 bytes inside of 528-byte region [0x6160002cc480,0x6160002cc690)
freed by thread T8 (check_loader) here:
    #0 0x7fc140ab1f1e in __interceptor_realloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10df1e)
    #1 0xea5d00d in Memory::realloc_static(void*, unsigned long, bool) core/os/memory.cpp:137
    #2 0xe57dee6 in CowData<VMap<Object::Signal::Target, Object::Signal::Slot>::Pair>::resize(int) core/cowdata.h:283
    #3 0xe57d763 in CowData<VMap<Object::Signal::Target, Object::Signal::Slot>::Pair>::insert(int, VMap<Object::Signal::Target, Object::Signal::Slot>::Pair const&) core/cowdata.h:175
    #4 0xe56e7d2 in VMap<Object::Signal::Target, Object::Signal::Slot>::insert(Object::Signal::Target const&, Object::Signal::Slot const&) core/vmap.h:125
    #5 0xe564d6d in VMap<Object::Signal::Target, Object::Signal::Slot>::operator[](Object::Signal::Target const&) core/vmap.h:199
    #6 0xe545fb2 in Object::connect(StringName const&, Object*, StringName const&, Vector<Variant> const&, unsigned int) core/object.cpp:1485
    #7 0xb1ea18d in StaticBody2D::set_physics_material_override(Ref<PhysicsMaterial> const&) scene/2d/physics_body_2d.cpp:260
    #8 0xa9501c9 in MethodBind1<Ref<PhysicsMaterial> const&>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:775
    #9 0xe2db298 in ClassDB::set_property(Object*, StringName const&, Variant const&, bool*) core/class_db.cpp:1031
    #10 0xe523e52 in Object::set(StringName const&, Variant const&, bool*) core/object.cpp:422
    #11 0xbf96281 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:253
    #12 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #13 0xbf928b7 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:138
    #14 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #15 0xbff8845 in MethodBind1RC<Node*, PackedScene::GenEditState>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:1333
    #16 0xe533842 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:921
    #17 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #18 0x1a182e9 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1078
    #19 0x18549c3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1173
    #20 0xe5333af in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:900
    #21 0xf0537e1 in _Thread::_start_func(void*) core/bind/core_bind.cpp:2660
    #22 0x4f831d5 in ThreadPosix::thread_callback(void*) drivers/unix/thread_posix.cpp:74
    #23 0x7fc140427668 in start_thread /build/glibc-4WA41p/glibc-2.30/nptl/pthread_create.c:479

previously allocated by thread T5 (check_loader) here:
    #0 0x7fc140ab1f1e in __interceptor_realloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10df1e)
    #1 0xea5d00d in Memory::realloc_static(void*, unsigned long, bool) core/os/memory.cpp:137
    #2 0xe57dee6 in CowData<VMap<Object::Signal::Target, Object::Signal::Slot>::Pair>::resize(int) core/cowdata.h:283
    #3 0xe57d763 in CowData<VMap<Object::Signal::Target, Object::Signal::Slot>::Pair>::insert(int, VMap<Object::Signal::Target, Object::Signal::Slot>::Pair const&) core/cowdata.h:175
    #4 0xe56e7d2 in VMap<Object::Signal::Target, Object::Signal::Slot>::insert(Object::Signal::Target const&, Object::Signal::Slot const&) core/vmap.h:125
    #5 0xe564d6d in VMap<Object::Signal::Target, Object::Signal::Slot>::operator[](Object::Signal::Target const&) core/vmap.h:199
    #6 0xe545fb2 in Object::connect(StringName const&, Object*, StringName const&, Vector<Variant> const&, unsigned int) core/object.cpp:1485
    #7 0xb1ea18d in StaticBody2D::set_physics_material_override(Ref<PhysicsMaterial> const&) scene/2d/physics_body_2d.cpp:260
    #8 0xa9501c9 in MethodBind1<Ref<PhysicsMaterial> const&>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:775
    #9 0xe2db298 in ClassDB::set_property(Object*, StringName const&, Variant const&, bool*) core/class_db.cpp:1031
    #10 0xe523e52 in Object::set(StringName const&, Variant const&, bool*) core/object.cpp:422
    #11 0xbf96281 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:253
    #12 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #13 0xbf928b7 in SceneState::instance(SceneState::GenEditState) const scene/resources/packed_scene.cpp:138
    #14 0xbfc6810 in PackedScene::instance(PackedScene::GenEditState) const scene/resources/packed_scene.cpp:1695
    #15 0xbff8845 in MethodBind1RC<Node*, PackedScene::GenEditState>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:1333
    #16 0xe533842 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:921
    #17 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #18 0x1a182e9 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1078
    #19 0x18549c3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1173
    #20 0xe5333af in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:900
    #21 0xf0537e1 in _Thread::_start_func(void*) core/bind/core_bind.cpp:2660
    #22 0x4f831d5 in ThreadPosix::thread_callback(void*) drivers/unix/thread_posix.cpp:74
    #23 0x7fc140427668 in start_thread /build/glibc-4WA41p/glibc-2.30/nptl/pthread_create.c:479

Thread T5 (check_loader) created by T0 here:
    #0 0x7fc1409de805 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x4f836d0 in ThreadPosix::create_func_posix(void (*)(void*), void*, Thread::Settings const&) drivers/unix/thread_posix.cpp:90
    #2 0xea70927 in Thread::create(void (*)(void*), void*, Thread::Settings const&) core/os/thread.cpp:51
    #3 0xf05524d in _Thread::start(Object*, StringName const&, Variant const&, _Thread::Priority) core/bind/core_bind.cpp:2706
    #4 0xf12c25d in MethodBind4R<Error, Object*, StringName const&, Variant const&, _Thread::Priority>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:3325
    #5 0xe533842 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:921
    #6 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #7 0x1a1836a in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1081
    #8 0x18549c3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1173
    #9 0xe5333af in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:900
    #10 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #11 0x1a1836a in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1081
    #12 0x1854edc in GDScriptInstance::call_multilevel(StringName const&, Variant const**, int) modules/gdscript/gdscript.cpp:1189
    #13 0x92e6e27 in Node::_notification(int) scene/main/node.cpp:60
    #14 0x171077b in Node::_notificationv(int, bool) scene/main/node.h:46
    #15 0x1712c25 in CanvasItem::_notificationv(int, bool) scene/2d/canvas_item.h:166
    #16 0xacfb56f in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:38
    #17 0xe533cd4 in Object::notification(int, bool) core/object.cpp:931
    #18 0x94137f1 in SceneTree::_notify_group_pause(StringName const&, int) scene/main/scene_tree.cpp:981
    #19 0x9404080 in SceneTree::idle(float) scene/main/scene_tree.cpp:527
    #20 0x1589ce8 in Main::iteration() main/main.cpp:2010
    #21 0x1483056 in OS_X11::run() platform/x11/os_x11.cpp:3255
    #22 0x13fe299 in main platform/x11/godot_x11.cpp:56
    #23 0x7fc13f58d1e2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x271e2)

Thread T8 (check_loader) created by T0 here:
    #0 0x7fc1409de805 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x4f836d0 in ThreadPosix::create_func_posix(void (*)(void*), void*, Thread::Settings const&) drivers/unix/thread_posix.cpp:90
    #2 0xea70927 in Thread::create(void (*)(void*), void*, Thread::Settings const&) core/os/thread.cpp:51
    #3 0xf05524d in _Thread::start(Object*, StringName const&, Variant const&, _Thread::Priority) core/bind/core_bind.cpp:2706
    #4 0xf12c25d in MethodBind4R<Error, Object*, StringName const&, Variant const&, _Thread::Priority>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:3325
    #5 0xe533842 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:921
    #6 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #7 0x1a1836a in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1081
    #8 0x18549c3 in GDScriptInstance::call(StringName const&, Variant const**, int, Variant::CallError&) modules/gdscript/gdscript.cpp:1173
    #9 0xe5333af in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:900
    #10 0xe7a6306 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1112
    #11 0x1a1836a in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1081
    #12 0x1854edc in GDScriptInstance::call_multilevel(StringName const&, Variant const**, int) modules/gdscript/gdscript.cpp:1189
    #13 0x92e6e27 in Node::_notification(int) scene/main/node.cpp:60
    #14 0x171077b in Node::_notificationv(int, bool) scene/main/node.h:46
    #15 0x1712c25 in CanvasItem::_notificationv(int, bool) scene/2d/canvas_item.h:166
    #16 0xacfb56f in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:38
    #17 0xe533cd4 in Object::notification(int, bool) core/object.cpp:931
    #18 0x94137f1 in SceneTree::_notify_group_pause(StringName const&, int) scene/main/scene_tree.cpp:981
    #19 0x9404080 in SceneTree::idle(float) scene/main/scene_tree.cpp:527
    #20 0x1589ce8 in Main::iteration() main/main.cpp:2010
    #21 0x1483056 in OS_X11::run() platform/x11/os_x11.cpp:3255
    #22 0x13fe299 in main platform/x11/godot_x11.cpp:56
    #23 0x7fc13f58d1e2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x271e2)

@kdlee
Copy link

kdlee commented Nov 26, 2021

Not sure if this a regression in 3.3 (commit 77d0412).
But I've also ran across crashes doing instance() from a thread at places like below.
Maybe I should try 3.4 now ...

StringName::operator<(const StringName & p_name) Line 100 (godot\core\string_name.h:100)
Comparator<StringName>::operator()(const StringName & p_a, const StringName & p_b) Line 292 (godot\core\typedefs.h:292)
Map<StringName,StringName,Comparator<StringName>,DefaultAllocator>::_find(const StringName & p_key) Line 241 (godot\core\map.h:241)
Map<StringName,StringName,Comparator<StringName>,DefaultAllocator>::find(const StringName & p_key) Line 533 (godot\core\map.h:533)
Shader::remap_param(const StringName & p_param) Line 92 (godot\scene\resources\shader.h:92)
ShaderMaterial::_get(const StringName & p_name, Variant & r_ret) Line 141 (godot\scene\resources\material.cpp:141)
ShaderMaterial::_getv(const StringName & p_name, Variant & r_ret) Line 78 (godot\scene\resources\material.h:78)
Object::get(const StringName & p_name, bool * r_valid) Line 516 (godot\core\object.cpp:516)
Resource::duplicate_for_local_scene(Node * p_for_scene, Map<Ref<Resource>,Ref<Resource>,Comparator<Ref<Resource>>,DefaultAllocator> & remap_cache) Line 167 (godot\core\resource.cpp:167)
SceneState::instance(SceneState::GenEditState p_edit_state) Line 246 (godot\scene\resources\packed_scene.cpp:246)
PackedScene::instance(PackedScene::GenEditState p_edit_state) Line 1706 (godot\scene\resources\packed_scene.cpp:1706)

@Zylann
Copy link
Contributor

Zylann commented Nov 26, 2021

FYI it doesnt seem mentionned in this issue, but since my last comment I learned that in Godot 3.x, PhysicsServer is not thread-safe, so creating an instance of any physics node or resource from a thread can break. At least that would explain the physics-related errors mentionned earlier.

@kdlee
Copy link

kdlee commented Nov 26, 2021

That's good to know, thanks for mentioning. The scene I was instancing just has 1 MeshInstance with 1 ShaderMaterial that has a NoiseTexture and another texture. Maybe some part of this code path also isn't thread safe for unexpected reasons.
BTW, also tried with latested 3.4 branch and still getting same crash.

@Zireael07
Copy link
Contributor

@kdlee: IIRC shader compiling isn't thread safe either, so instancing any meshes can/will lag and have issues.

@kdlee
Copy link

kdlee commented Nov 26, 2021

@Zireael07: Ah thanks, I think this explains. If I preload the scene from main thread, and turn off 'Local To Scene' for this ShaderMaterial that's being instanced, seems to not crash. I guess 'Local To Scene' is causing each instance() to recompile the shader while that doesn't work in threads?

EDIT: Actually from debugging, seems like shader compile only happens once on main thread when I preload. There seems to be just some issue with cloning 'Local To Scene' ShaderMaterial from another thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants