From 3e792e6cd7555ac6ceb7ef356f6bbd2e86758e2e Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 19 May 2023 13:52:30 +0200 Subject: [PATCH] Add `NativeInteropException` for native interop crashes --- Source/Engine/Engine/NativeInterop.Managed.cs | 8 ++++---- .../Engine/Engine/NativeInterop.Unmanaged.cs | 2 +- Source/Engine/Engine/NativeInterop.cs | 19 ++++++++++++++++--- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.Managed.cs b/Source/Engine/Engine/NativeInterop.Managed.cs index 41ace593b..bc240275f 100644 --- a/Source/Engine/Engine/NativeInterop.Managed.cs +++ b/Source/Engine/Engine/NativeInterop.Managed.cs @@ -261,7 +261,7 @@ namespace FlaxEngine.Interop return; } - throw new Exception("Tried to free non-pooled ManagedArray as pooled ManagedArray"); + throw new NativeInteropException("Tried to free non-pooled ManagedArray as pooled ManagedArray"); } } } @@ -499,7 +499,7 @@ namespace FlaxEngine.Interop else if (weakPoolOther.TryGetValue(handle, out value)) return value; - throw new Exception("Invalid ManagedHandle"); + throw new NativeInteropException("Invalid ManagedHandle"); } internal static void SetObject(IntPtr handle, object value) @@ -527,7 +527,7 @@ namespace FlaxEngine.Interop else if (weakPoolOther.ContainsKey(handle)) weakPoolOther[handle] = value; - throw new Exception("Invalid ManagedHandle"); + throw new NativeInteropException("Invalid ManagedHandle"); } internal static void FreeHandle(IntPtr handle) @@ -556,7 +556,7 @@ namespace FlaxEngine.Interop else return; - throw new Exception("Invalid ManagedHandle"); + throw new NativeInteropException("Invalid ManagedHandle"); } } } diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index bc2af6d61..c079a14e1 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -1157,7 +1157,7 @@ namespace FlaxEngine.Interop case Type _ when type.IsClass: monoType = MTypes.Object; break; - default: throw new Exception($"Unsupported type '{type.FullName}'"); + default: throw new NativeInteropException($"Unsupported type '{type.FullName}'"); } return (uint)monoType; } diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 39adc59ab..52dc82fce 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -87,7 +87,7 @@ namespace FlaxEngine.Interop #endif scriptingAssemblyLoadContext = new AssemblyLoadContext("Flax", isCollectible); #if FLAX_EDITOR - scriptingAssemblyLoadContext.Resolving += ScriptingAssemblyLoadContext_Resolving; + scriptingAssemblyLoadContext.Resolving += OnScriptingAssemblyLoadContextResolving; #endif } @@ -106,7 +106,8 @@ namespace FlaxEngine.Interop DelegateHelpers.InitMethods(); } - private static Assembly? ScriptingAssemblyLoadContext_Resolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName) +#if FLAX_EDITOR + private static Assembly? OnScriptingAssemblyLoadContextResolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName) { // FIXME: There should be a better way to resolve the path to EditorTargetPath where the dependencies are stored string editorTargetPath = Path.GetDirectoryName(nativeLibraryPaths.Keys.First(x => x != "FlaxEngine")); @@ -116,6 +117,7 @@ namespace FlaxEngine.Interop return assemblyLoadContext.LoadFromAssemblyPath(assemblyPath); return null; } +#endif [UnmanagedCallersOnly] internal static unsafe void Exit() @@ -523,7 +525,7 @@ namespace FlaxEngine.Interop } } - throw new Exception($"Invalid field {field.Name} to marshal for type {typeof(T).Name}"); + throw new NativeInteropException($"Invalid field {field.Name} to marshal for type {typeof(T).Name}"); } private static void ToManagedFieldPointer(FieldInfo field, ref T fieldOwner, IntPtr fieldPtr, out int fieldOffset) @@ -1271,6 +1273,17 @@ namespace FlaxEngine.Interop } #endif } + + internal class NativeInteropException : Exception + { + public NativeInteropException(string message) + : base(message) + { +#if !BUILD_RELEASE + Debug.Logger.LogHandler.LogWrite(LogType.Error, "Native interop exception!"); +#endif + } + } } #endif