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

ExceptionInterop.cs « exceptioninterop « exceptions « baseservices « tests « src - github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1c6f43e12e4a45e0d264696b9c23e8ef7b73da4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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);

        // Aggressively 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);
    }
}