Godot: Multiple asynchronous invocations of ResourceInteractiveLoader.Poll() crashes Godot in C#

Created on 1 Apr 2018  路  9Comments  路  Source: godotengine/godot

Godot version:
master / dad47d8876de45132226985dbbd079e060f6facc

OS/device including version:
_Manjaro Linux 17.1_

Issue description:
When using ResourceInteractiveLoader in a thread or async method in C#, a consecutive invocation of Poll always results in a crash of the runtime:

```c#
new Thread(() =>
{
var loader = ResourceLoader.LoadInteractive("res://MyScene.tscn");

loader.Poll(); // This runs ok.
loader.Poll(); // This results in a crash.

}).Start();

The stacktrace is as follows:

Stacktrace:
at <0xffffffff>
at (wrapper managed-to-native) Godot.NativeCalls.godot_icall_0_326 (intptr,intptr) [0x00008] in :0
at Godot.ResourceInteractiveLoader.Poll () [0x00000] in /home/fender/.local/share/godot/mono/solutions/GodotSharp_-268592726416686496/ObjectType/ResourceInteractiveLoader.cs:35
at AlleyCat.IO.ResourceMonitor/<>c__DisplayClass0_0`1.b__0 () [0x00036] in /home/fender/workspace/AlleyCat/Source/AlleyCat/IO/ResourceMonitor.cs:42
at System.Threading.Tasks.Task.InnerInvoke () [0x0000f] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2501
at System.Threading.Tasks.Task.Execute () [0x00000] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2344
at System.Threading.Tasks.Task.ExecutionContextCallback (object) [0x00006] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2488
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00071] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:961
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00000] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:908
at System.Threading.Tasks.Task.ExecuteWithThreadLocal (System.Threading.Tasks.Task&) [0x00034] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/mcs/class/corlib/corert/Task.cs:72
at System.Threading.Tasks.Task.ExecuteEntry (bool) [0x0004a] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2410
at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00000] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2359
at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:858
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000] in /tmp/yaourt-tmp-fender/aur-mono-nightly/src/mono-5.13.0.302/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1213
at (wrapper runtime-invoke) .runtime_invoke_bool (object,intptr,intptr,intptr) [0x0001f] in <5e50226ee74345998144742acb82f42a>:0
...

Native stacktrace:
/usr/lib/libmonosgen-2.0.so.1(+0xe4605) [0x7fd341cc8605]
/usr/lib/libmonosgen-2.0.so.1(+0x1584f1) [0x7fd341d3c4f1]
/usr/lib/libGLdispatch.so.0(+0x484c9) [0x7fd33f2984c9]
...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x00007fd340a0497b in poll () from /usr/lib/libc.so.6
Id Target Id Frame

  • 1 Thread 0x7fd34404bfc0 (LWP 24054) "godot" 0x00007fd340a0497b in poll () from /usr/lib/libc.so.6
    2 Thread 0x7fd3440a7700 (LWP 24055) "godot" 0x00007fd34127dcf6 in do_futex_wait.constprop () from /usr/lib/libpthread.so.0
    3 Thread 0x7fd339c6c700 (LWP 24056) "godot" 0x00007fd34127dcf6 in do_futex_wait.constprop () from /usr/lib/libpthread.so.0
    4 Thread 0x7fd335c2b700 (LWP 24057) "threaded-ml" 0x00007fd340a0497b in poll () from /usr/lib/libc.so.6
    5 Thread 0x7fd33542a700 (LWP 24058) "godot" 0x00007fd34127b3bd in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
    6 Thread 0x7fd33405e700 (LWP 24059) "godot" 0x00007fd3409dcb10 in nanosleep () from /usr/lib/libc.so.6
    7 Thread 0x7fd3227ff700 (LWP 24060) "SGen worker" 0x00007fd34127b3bd in pthread_cond_wait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
    8 Thread 0x7fd320ffe700 (LWP 24061) "Finalizer" 0x00007fd34127dcf6 in do_futex_wait.constprop () from /usr/lib/libpthread.so.0
    9 Thread 0x7fd32082f700 (LWP 24062) "Debugger agent" 0x00007fd34127ecab in accept () from /usr/lib/libpthread.so.0
    10 Thread 0x7fd3204ff700 (LWP 24063) "godot" 0x00007fd34127b6fd in pthread_cond_timedwait@@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
    11 Thread 0x7fd3202fe700 (LWP 24064) "Thread Pool Wor" 0x00007fd34127f6b7 in waitpid () from /usr/lib/libpthread.so.0
    12 Thread 0x7fd3157fc700 (LWP 24065) "Thread Pool Wor" 0x00007fd34127dee0 in do_futex_wait () from /usr/lib/libpthread.so.0

```

bug mono

All 9 comments

That class is not really meant to be used like that, reading resources is always sequential.

@reduz Thanks for the information! I think I got a wrong impression from this :

As an excuse, I haven't yet studied resource_queue.gd thoroghly to figure out how exactly ResourceInteractiveLoader could be used in an asynchronous context.

I just skimmed through the source and found this part (_edited to include only the relevant lines_):

func start():
    thread = Thread.new()
    thread.start(self, "thread_func", 0)
func thread_func(u):
    while true:
        thread_process()
func thread_process():
    while queue.size() > 0:
        var ret = res.poll()

You can close this issue, if it's just from my misunderstanding.

@BrentAFlynn That makes me even more confused, unfortunately. Does it mean ResourceInteractiveLoader wouldn't work asynchronously only in C#?

@mysticfall This is not related to C# or GDScript, that class is not meant to work like that, I would like to know where you got the impression of it so we can fix the docs. There is even a tutorial on how to use it:
http://docs.godotengine.org/en/3.0/tutorials/io/background_loading.html

In any case, closing.

@reduz The documentation you linked includes a section called _"Using multiple threads"_ which reads:

ResourceInteractiveLoader can be used from multiple threads.

But as my code snippet shows, it seems that the API can't be invoked from a different thread (at least a C# one) at all. Am I misunderstanding something?

Indeed, that documentation page indicates it can be used like this. Would be great if @reduz could clarify this.

Any way, I'm going to check if this issue is actually related to C# or not.

I've tested this on latest master. I could not reproduce the crash on Windows, only on Linux. The backtrace is:

Thread 10 "Thread Pool Wor" received signal SIGSEGV, Segmentation fault.
[Cambiando a Thread 0x7fffd122a700 (LWP 17996)]
0x00007ffff3e814c9 in ?? () from /usr/lib/x86_64-linux-gnu/libGLdispatch.so.0
(gdb) bt
#0  0x00007ffff3e814c9 in ?? () from /usr/lib/x86_64-linux-gnu/libGLdispatch.so.0
#1  0x0000000001ea968c in RasterizerStorageGLES3::texture_create (this=0x5502da0) at drivers/gles3/rasterizer_storage_gles3.cpp:615
#2  0x0000000003367387 in VisualServerRaster::texture_create (this=0x54feb40) at servers/visual/visual_server_raster.h:149
#3  0x000000000339c32e in VisualServerWrapMT::texture_create (this=0x555a2b0) at servers/visual/visual_server_wrap_mt.h:84
#4  0x00000000030b8f4c in StreamTexture::StreamTexture (this=0x7fffac024f50) at scene/resources/texture.cpp:835
#5  0x00000000030cdd96 in Ref<StreamTexture>::instance (this=0x7fffd1228fe0) at ./core/reference.h:275
#6  0x00000000030b90a6 in ResourceFormatLoaderStreamTexture::load (this=0x5fe16a0, p_path=..., p_original_path=..., r_error=0x0)
    at scene/resources/texture.cpp:846
#7  0x0000000003782123 in ResourceLoader::_load (p_path=..., p_original_path=..., p_type_hint=..., p_no_cache=false, r_error=0x0)
    at core/io/resource_loader.cpp:266
#8  0x000000000377cd64 in ResourceFormatImporter::load (this=0x5174090, p_path=..., p_original_path=..., r_error=0x0)
    at core/io/resource_import.cpp:125
#9  0x0000000003782123 in ResourceLoader::_load (p_path=..., p_original_path=..., p_type_hint=..., p_no_cache=false, r_error=0x0)
    at core/io/resource_loader.cpp:266
#10 0x000000000378264c in ResourceLoader::load (p_path=..., p_type_hint=..., p_no_cache=false, r_error=0x0)
    at core/io/resource_loader.cpp:328
#11 0x0000000003058c99 in ResourceInteractiveLoaderText::poll (this=0x7fffac014120) at scene/resources/scene_format_text.cpp:432
#12 0x0000000002093408 in MethodBind0R<Error>::ptrcall (this=0x51b7800, p_object=0x7fffac014120, p_args=0x0, r_ret=0x7fffd1229330)
    at ./core/method_bind.gen.inc:229
#13 0x000000000195cd3d in godot_icall_0_326 (method=0x51b7800, ptr=0x7fffac014120) at modules/mono/glue/mono_glue.gen.cpp:3571
#14 0x000000004016ced4 in ?? ()
#15 0x0000000000000000 in ?? ()

The line is: https://github.com/godotengine/godot/blob/07e2046980c903268ef0d2f5a73caea77d511519/drivers/gles3/rasterizer_storage_gles3.cpp#L615

After some more debugging I concluded the use of ResourceInteractiveLoader here is correct and this issue is being caused by #23709.

Fixed by #25300

Was this page helpful?
0 / 5 - 0 ratings