为什么 .NET Native 上的 Raygun 会导致我的应用程序崩溃?

Why does Raygun on .NET Native cause my app to crash?

我正在开发 Windows 10 Store 应用程序,我正在使用 Raygun.io (5.2.0)。我们发布了该应用程序几次(最近一次是在 12 月中旬),我在 Rayguns 网络界面中看到来自以前版本的日志。在发布下一个版本之前测试应用程序时,我发现如果应用程序是使用 .NET 本机工具链构建的,则在发送异常时 Raygun 不再工作(= 崩溃)。 我可以在一个简单的 UWP 测试应用程序中重现它:

public sealed partial class MainPage : Page
{
    //private readonly RaygunClient _raygunClient;

    public MainPage()
    {
        InitializeComponent();

        RaygunClient.Attach("<app_key>");
        //_raygunClient = new RaygunClient("<app_key>");
    }

    private async void OnClick(object sender, RoutedEventArgs e)
    {
        try
        {
            // this is crashing the app when project is build using .NET native toolchain
            // it is not even throwing exception
            //await _raygunClient.SendAsync(new InvalidOperationException("Raygun Test"));
            await RaygunClient.Current.SendAsync(new InvalidOperationException("Raygun Test")); // (1)
            Status.Text = "Ok";
        }
        catch (Exception exception) // (2)
        {
            Status.Text = $"Failed with {exception.Message}";
        }
    }
}

检查 https://github.com/MindscapeHQ/raygun4net 支持 platforms/frameworks,它似乎不明确支持 UWP。

更新:应用程序在第(1)行之后被杀死,没有异常被捕获到(2) 在事件视图中我可以看到:

Faulting application name: rayguntest.exe, version: 1.0.0.0, time stamp: 0x56a0edc9
Faulting module name: mrt100_app.dll, version: 1.0.23406.0, time stamp: 0x561408ce
Exception code: 0x80000003
Fault offset: 0x000000000000a0ad
Faulting process id: 0x305c
Faulting application start time: 0x01d1545a0fea5649
Faulting application path: C:\Projects\rayguntest\rayguntest\bin\x64\Release\AppX\rayguntest.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.NET.Native.Runtime.1.1_1.1.23406.0_x64__8wekyb3d8bbwe\mrt100_app.dll
Report Id: 52bbeeb5-97c6-4814-b5dc-51ee6c3fa9bd
Faulting package full name: 6ca59c51-ed22-482b-acf6-12d241079f4d_1.0.0.0_x64__1d8r4kqm7qz2y
Faulting package-relative application ID: App

摘自微软:

If the necessary metadata or implementation code is absent at runtime, the .NET Native runtime throws an exception. You can prevent these exceptions, and ensure that the .NET Native tool chain includes the required metadata and implementation code, by using a runtime directives file, an XML file that designates the program elements whose metadata or implementation code must be available at runtime and assigns a runtime policy to them.

来自 Microsoft .NET Native and Compilation

The resulting app that is produced by the .NET Native tool chain is written to a directory named ilc.out in the Debug or Release directory of your project directory. It consists of the following files:

appName.exe, a stub executable that simply transfers control to a special Main export in appName.dll.

appName.dll, a Windows dynamic link library that contains all your application code, as well as code from the .NET Framework Class Library and any third-party libraries that you have a dependency on. It also contains support code, such as the code necessary to interoperate with Windows and to serialize objects in your app.

•mrt100_app.dll, a refactored runtime that provides runtime services such as garbage collection.

我们已经完成调查,这确实是 .NET Native 中的一个错误。问题是在某些情况下我们没有正确处理所有涉及无效转换的情况。特别是将 Arrays 转换为具有多个泛型参数的泛型类型。您可以通过检查 SimpleJson.SerializeValue 查看 Raygun 中我们将 运行 解决问题的地方: https://github.com/MindscapeHQ/raygun4net/blob/67c4bb9fd660afb91d62e9333d75a36a85ee5d4f/Mindscape.Raygun4Net/SimpleJson.cs#L1016

一种解决方法是首先避免让此代码路径序列化数组。另一个是修补 RayGun 以首先检查数组大小写并避免它试图做的所有其他猜测。

您没有看到异常的原因是因为 运行time 对各种断言和跌落低谷具有很强的防御性,因此在这些情况下它调用 OS FailFast。

希望对您有所帮助。