IronLanguages / ironpython2

Implementation of the Python programming language for .NET Framework; built on top of the Dynamic Language Runtime (DLR).

Home Page:http://ironpython.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Intermittent crashes when hosted on Unity when IronPython iterates over a C# collection

krajzeg opened this issue · comments

Description

I'm using IronPython (2.7.10) hosted within Unity (2020.1.3) and I'm getting weird, intermittent crashes from script code. Basically, every time Python code iterates over a C# enumerable (doesn't matter if it's an array, a list, LINQ object, etc.), there is a small chance of it segfaulting somewhere within the Mono runtime.

This only has a chance of happening the first time the Python code is executed. If the code runs cleanly once, it runs stable forever. This is true even if I disable compilation and make sure all runs are interpreted.

Attached is a reproduction project for Unity. After talking with @slozier on Gitter, I tried to reproduce the issue outside of the Unity Editor, using the exact Mono runtime shipping with Unity - it failed to reproduce there, so it's something to do with running in the Unity environment.

Relevant part of the stacktrace:

0x00007FFAED92F591 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\metadata.c:5360] mono_metadata_class_equal 
0x00007FFAED935ED2 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\metadata.c:5538] mono_metadata_signature_equal 
0x00007FFAED8A2399 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\eglib\ghashtable.c:311] monoeg_g_hash_table_lookup 
0x00007FFAED923010 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\marshal.c:3604] mono_marshal_get_delegate_invoke_internal 
0x00007FFAEDAA97F6 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-trampolines.c:1262] mono_delegate_trampoline 
  ERROR: SymGetSymFromAddr64, GetLastError: 'Nie można odnaleźć określonego modułu.' (Address: 000001FDDA7D1073)
  ERROR: SymGetModuleInfo64, GetLastError: 'Procedura inicjowania biblioteki dołączanej dynamicznie (DLL) nie powiodła się.' (Address: 000001FDDA7D1073)
0x000001FDDA7D1073 ((<unknown>)) (function-name not available)
0x000001FEA368D040 (Mono JIT Code) System.Dynamic.UpdateDelegates:UpdateAndExecute1<object, System.Collections.Generic.KeyValuePair`2<System.Collections.IEnumerator, System.IDisposable>> (System.Runtime.CompilerServices.CallSite,object)
0x000001FEA368D395 (Mono JIT Code) (wrapper delegate-invoke) System.Func`3<System.Runtime.CompilerServices.CallSite, object, System.Collections.Generic.KeyValuePair`2<System.Collections.IEnumerator, System.IDisposable>>:invoke_TResult_T1_T2 (System.Runtime.CompilerServices.CallSite,object)
0x000001FEA368CAAF (Mono JIT Code) Microsoft.Scripting.Interpreter.DynamicInstruction`2<object, System.Collections.Generic.KeyValuePair`2<System.Collections.IEnumerator, System.IDisposable>>:Run (Microsoft.Scripting.Interpreter.InterpretedFrame)
0x000001FEA3589078 (Mono JIT Code) Microsoft.Scripting.Interpreter.Interpreter:Run (Microsoft.Scripting.Interpreter.InterpretedFrame)
0x000001FEA3587B63 (Mono JIT Code) Microsoft.Scripting.Interpreter.LightLambda:Run2<T0_REF, T1_REF, TRet_REF> (T0_REF,T1_REF)
0x000001FEA367D38C (Mono JIT Code) IronPython.Compiler.PythonCallTargets:OriginalCallTarget1 (IronPython.Runtime.PythonFunction,object)
0x000001FEA3590631 (Mono JIT Code) (wrapper dynamic-method) object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object,System.Collections.Generic.IEnumerable`1<int>)
0x000001FEA35A3A32 (Mono JIT Code) System.Dynamic.UpdateDelegates:UpdateAndExecute2<T0_REF, T1_REF, TRet_REF> (System.Runtime.CompilerServices.CallSite,T0_REF,T1_REF)
0x000001FEA3590443 (Mono JIT Code) (wrapper dynamic-method) object:_Scripting_ (object[],System.Collections.Generic.IEnumerable`1<int>)
0x000001FE3EDDAB3D (Mono JIT Code) [C:\prod\proj\smiecie\ironpython-repro-case\Assets\IronPythonIssue.cs:27] IronPythonIssue:Update () 
...

Steps to reproduce

Unfortunately, the issue only appears within Unity, and only the first time a Unity "scene" is run. This means that you have to load up the repro case in Unity and "play" the scene several times (possibly around 50-60, unfortunately) to make it crash. The repro case will automatically stop if there is no crash to make this process faster.

Reproduction project: ironpython-repro-case.zip

I tried to create a more reliable repro case, but this issue only ever happens on the first run of the code, meaning that looping over it cannot make it happen more reliably.

Versions

This happens with IronPython 2.7.10 DLLs when used on any Unity 2019.2 and above (possibly earlier versions as well). Unity uses a 5.11.0 Mono runtime with their own (undisclosed) modifications.

This issue was fixed on the Unity end, so it turns out it was not IronPython's fault in this case. It seems to have been a general problem with Unity's Editor not cleaning up stuff properly on play, which I assume caused a "stale" method to be executed, leading to a crash.

Resolution Note (fix version 2021.1):
Fixed issue with dynamic methods not being cleaned up on domain reload which would lead to corrupted data that would then cause this crash.
Fixed in: 2021.1.0a1

Should be safe to close this. The issue is present in Unity 2019.1.x and higher and will only be fixed in the upcoming 2021.1.x branch, so you might still have to live with this for a while when using IronPython with Unity.