Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jekoritz@microsoft.com>2022-06-22 23:06:00 +0300
committerGitHub <noreply@github.com>2022-06-22 23:06:00 +0300
commitf20a046986c37201c9e64320b5a8e37581d75694 (patch)
treef27bfcbca99e82f6e5fedc2b6bd9ada64d81f600 /src/tests/baseservices
parent4388cc5bd557010b673fe307c26b4d41ecdbb6f6 (diff)
Add exception interop test for validating native exception interop on Windows + CoreCLR. (#70110)
Diffstat (limited to 'src/tests/baseservices')
-rw-r--r--src/tests/baseservices/exceptions/exceptioninterop/CMakeLists.txt4
-rw-r--r--src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.cs125
-rw-r--r--src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.csproj10
-rw-r--r--src/tests/baseservices/exceptions/exceptioninterop/ExceptionInteropNative.cpp19
-rw-r--r--src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop_ro.csproj14
5 files changed, 172 insertions, 0 deletions
diff --git a/src/tests/baseservices/exceptions/exceptioninterop/CMakeLists.txt b/src/tests/baseservices/exceptions/exceptioninterop/CMakeLists.txt
new file mode 100644
index 00000000000..a477a57c1cd
--- /dev/null
+++ b/src/tests/baseservices/exceptions/exceptioninterop/CMakeLists.txt
@@ -0,0 +1,4 @@
+
+include_directories(${INC_PLATFORM_DIR})
+add_library(ExceptionInteropNative SHARED ExceptionInteropNative.cpp)
+target_link_libraries(ExceptionInteropNative PRIVATE platformdefines) \ No newline at end of file
diff --git a/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.cs b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.cs
new file mode 100644
index 00000000000..f9f18b91369
--- /dev/null
+++ b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.cs
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Xunit;
+using static ExceptionInteropNative;
+
+internal unsafe static class ExceptionInteropNative
+{
+ [DllImport(nameof(ExceptionInteropNative))]
+ public static extern void ThrowException();
+
+ [DllImport(nameof(ExceptionInteropNative))]
+ public static extern void NativeFunction();
+
+ [DllImport(nameof(ExceptionInteropNative))]
+ public static extern void CallCallback(delegate* unmanaged<void> cb);
+}
+
+public unsafe static class ExceptionInterop
+{
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ [SkipOnMono("Exception interop not supported on Mono.")]
+ public static void ThrowNativeExceptionAndCatchInFrame()
+ {
+ bool caughtException = false;
+ try
+ {
+ ThrowException();
+ }
+ catch
+ {
+ caughtException = true;
+ // Try calling another P/Invoke in the catch block to make sure we have everything set up
+ // to recover from the exceptional control flow.
+ NativeFunction();
+ }
+ Assert.True(caughtException);
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ [SkipOnMono("Exception interop not supported on Mono.")]
+ public static void ThrowManagedExceptionThroughNativeAndCatchInFrame()
+ {
+ bool caughtException = false;
+ try
+ {
+ CallCallback(&ThrowManagedException);
+ }
+ catch
+ {
+ caughtException = true;
+ // Try calling another P/Invoke in the catch block to make sure we have everything set up
+ // to recover from the exceptional control flow.
+ NativeFunction();
+ }
+ Assert.True(caughtException);
+
+ [UnmanagedCallersOnly]
+ static void ThrowManagedException()
+ {
+ throw new Exception();
+ }
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ [SkipOnMono("Exception interop not supported on Mono.")]
+ public static void ThrowNativeExceptionAndCatchInFrameWithFilter()
+ {
+ bool caughtException = false;
+ try
+ {
+ ThrowException();
+ }
+ catch (Exception) when (Filter())
+ {
+ caughtException = true;
+ // Try calling another P/Invoke in the catch block to make sure we have everything set up
+ // to recover from the exceptional control flow.
+ NativeFunction();
+ }
+ Assert.True(caughtException);
+
+ // Aggresively inline to make sure the call to NativeFunction is in the filter clause
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ bool Filter()
+ {
+ NativeFunction();
+ return true;
+ }
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ [SkipOnMono("Exception interop not supported on Mono.")]
+ public static void ThrowNativeExceptionAndCatchInFrameWithFinally()
+ {
+ bool caughtException = false;
+ try
+ {
+ try
+ {
+ ThrowException();
+ }
+ finally
+ {
+ // Try calling another P/Invoke in the finally block before the catch
+ // to make sure we have everything set up
+ // to recover from the exceptional control flow.
+ NativeFunction();
+ }
+ }
+ catch
+ {
+ caughtException = true;
+ }
+
+ Assert.True(caughtException);
+ }
+} \ No newline at end of file
diff --git a/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.csproj b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.csproj
new file mode 100644
index 00000000000..d553892a3b2
--- /dev/null
+++ b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop.csproj
@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <CMakeProjectReference Include="CMakeLists.txt" />
+ <Compile Include="ExceptionInterop.cs" />
+ </ItemGroup>
+ </Project>
+ \ No newline at end of file
diff --git a/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInteropNative.cpp b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInteropNative.cpp
new file mode 100644
index 00000000000..2d141792dd7
--- /dev/null
+++ b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInteropNative.cpp
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include <exception>
+#include <platformdefines.h>
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE ThrowException()
+{
+ throw std::exception{};
+}
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE NativeFunction()
+{
+}
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE CallCallback(void (*cb)())
+{
+ cb();
+} \ No newline at end of file
diff --git a/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop_ro.csproj b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop_ro.csproj
new file mode 100644
index 00000000000..99c7f983705
--- /dev/null
+++ b/src/tests/baseservices/exceptions/exceptioninterop/ExceptionInterop_ro.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CMakeProjectReference Include="CMakeLists.txt" />
+ <Compile Include="ExceptionInterop.cs" />
+ </ItemGroup>
+ </Project>
+ \ No newline at end of file