keijiro / KlakHap

HAP video player plugin for Unity
Other
341 stars 27 forks source link

ArrayTypeMismatchException in ReaderThread happens sometimes #27

Closed marijneken closed 4 years ago

marijneken commented 4 years ago

The following exception sometimes occurs at runtime, after running for multiple hours. I'm playing two HAP videos at the same time of about 40 seconds length. When they are done, they are manually restarted (in code) so I can sync them with sound playback. This is on Linux (Ubuntu). I've never even seen this C# exception before and I don't understand it at all. How can it be possible to access an Array element as the wrong type? Do you have any ideas why this could happen? And why it is not all the time, but only sometimes?

player.x86_64[1959]: ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.
player.x86_64[1959]:   at (wrapper stelemref) System.Object.virt_stelemref_sealed_class(intptr,object)
player.x86_64[1959]:   at System.Collections.Generic.List`1[T].Add (T item) [0x0001e] in <d7ac571ca2d04b2f981d0d886fa067cf>:0
player.x86_64[1959]:   at Klak.Hap.StreamReader.ReaderThread () [0x0009b] in <8c11eb63c8154898ad94ab5fceee64fa>:0
player.x86_64[1959]:   at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00014] in <d7ac571ca2d04b2f981d0d886fa067cf>:0
player.x86_64[1959]:   at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, Sys
player.x86_64[1959]:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Bool
player.x86_64[1959]:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x0002b] i
player.x86_64[1959]:   at System.Threading.ThreadHelper.ThreadStart () [0x00008] in <d7ac571ca2d04b2f981d0d886fa067cf>:0
player.x86_64[1959]: UnityEngine.DebugLogHandler:Internal_LogException()
player.x86_64[1959]: UnityEngine.DebugLogHandler:LogException(Exception, Object)
player.x86_64[1959]: UnityEngine.Logger:LogException(Exception, Object)
player.x86_64[1959]: UnityEngine.Debug:LogException(Exception)
player.x86_64[1959]: UnityEngine.UnhandledExceptionHandler:<RegisterUECatcher>m__0(Object, UnhandledExceptionEventArgs)
keijiro commented 4 years ago

Thanks for reporting it. Actually, I don't have any idea about what's happening in it. Would it be possible to share a minimum project that can reproduce the issue?

marijneken commented 4 years ago

Good idea. This has only happened in the production environment on 2 of the 15 machines this is running on. And randomly, after a few hours of normal operation. So, I fear it will be difficult to reproduce. But I can certainly try to create a small project and see if I can trigger this problem somehow. Could this be some kind of interference between the two running KlakHAP instances accessing some shared state? Some kind of race condition? I'm thinking that maybe something weird happens, just at the moment when the videos end and I restart them both, depending on the timing of when that exactly happens during the frame. Also, as you see in the stack trace, the List<>.Add() method is being called. Do you have any idea where in your code that call happens? I'm thinking that won't be a call that's made during the playback of video, but rather at the moment a video is started.

keijiro commented 4 years ago

Thanks for the additional information. I dug around issue trackers and forums, and I got the impression that these ArrayTypeMismatchException issues are caused by the mono compiler. I guess it doesn't reproduce on IL2CPP, that's not an available option on Linux though.

This is a kind of voodoo, but the situation would be probably changed by tweaking the compiler options. How about changing the API compatibility level and optimization options?

marijneken commented 4 years ago

Thank you for looking into it so deeply. And that's tough luck for me on this error. Did you get any idea on when this error happens? It seems to be timing dependent or otherwise not consistent, because it only happens quite rarely. This makes it difficult to track down and debug as well.

I will certainly look at those compiler options. I think I'm stuck on a particular API compatibility level though, because I'm using a serial connection via USB that needs the Serial class. But let's see what the optimization settings can do.

keijiro commented 4 years ago

This kind of compiler issues are quite hard to predict when it happens. Actually, I have no idea when/how it happens.

Also it's recommended to use newer versions of runtime. By the way, which version of Unity are you using for the project?

marijneken commented 4 years ago

But we do know it's in THIS line of the code, right?

    // Flush out the current contents of the lead queue.
    lock (_queueLock) while (_leadQueue.Count > 0)
        _freeBuffers.Add(_leadQueue.Dequeue());

Since that is the only List.Add() call that happens within ReaderThread().

Since this involves threads and locks, could it be related to that maybe?

This project was compiled with Unity 2018.3.9f1. What higher version would you recommend? The 2018 LTS version or even a stable version of 2019?

marijneken commented 4 years ago

Oh and by the way, these are my compiler settings: image

keijiro commented 4 years ago

The exception is thrown inside _freeBuffers.Add. It implies that there are some issues in the implementation of List<T>.Add or the C# compiler/runtime.

I saw a similar issue was fixed in the recent version of Mono. I'm not sure if the fix has been merged to Unity, but it's perhaps fixed in the latest version (2019.3) of Unity.

keijiro commented 4 years ago

I'm closing this issue now as I assume it's solved in the latest versions of Unity. Please reopen it if it reproduces with the latest version.