Asp.net Core 如何记录 System.AccessViolationException

Posted

技术标签:

【中文标题】Asp.net Core 如何记录 System.AccessViolationException【英文标题】:Asp.net Core How To Log System.AccessViolationException 【发布时间】:2021-09-30 02:10:14 【问题描述】:

我们最近发现我们的应用程序在使用一些第三方库进行一些非托管内存访问时抛出System.AccessViolationException。 我肯定会尝试与第三方合作以从他们那里获得修复,但这篇文章不是为了那个:)。

我希望对如何将异常信息实际获取到我的日志中获得一些见解。我们正在运行 Asp.net Core 5。 我们仅通过启用stdoutLogEnabled :https://docs.microsoft.com/en-us/aspnet/core/test/troubleshoot-azure-iis?view=aspnetcore-5.0#aspnet-core-module-stdout-log-iis 才发现此错误。但是,不建议将其用于生产环境。 所以我目前的问题是,我如何才能真正捕获相同的日志消息stdoutLogEnabled=true 能够通过使用其他一些日志记录提供程序(即Log4Net)给我们。

我的 appsettings 中有以下内容:

"Logging": 
    "LogLevel": 
      "Default": "Trace",
    
  ,

然而,当我运行一些不安全的代码来模拟 System.AccessViolationException 时,我看不到是否登录了我的任何 log4net 附加程序。

我不需要专门为 log4net 工作,这正是我们今天使用的。一般来说,我希望能够使用一些高级日志提供程序来捕获此日志,以便它可能在服务器上的本地文件以外的地方记录。

服务器上stdoutLogEnabled 的日志输出示例

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Repeat 2 times:
--------------------------------
   at   +.(IntPtr, System.String, Byte[], Int32, IntPtr ByRef, Int32 ByRef, IntPtr ByRef, System.String ByRef)
--------------------------------
   at d.(  , System.String, System.IO.Stream)
   at ThirdPartyClass.Save(System.String, System.IO.Stream)
   at FirstPartyClass.CreateImage()
   at FirstPartyClass.Execute()
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart()

编辑: 添加更多信息。我确实读过这篇类似的帖子:Gracefully handling corrupted state exceptions in .NET Core 这对我的问题来说不是个好兆头。我的问题确实不同,因为我不在乎捕捉异常,我对应用程序崩溃没意见。我只是想确保当这些错误确实发生时,我们可以将此信息记录到我们选择的日志提供程序。

【问题讨论】:

【参考方案1】:

如果你没有尝试,你可以使用 ILogger 接口或 Serilog 包。您可以从以下链接中找到帮助文档。

Logging in .NET Core and ASP.NET Core

Serilog

【讨论】:

您是否确切地知道 Serilog 是否会偶然捕获这些类型的异常?我会用 Serilog 做一个 POC 来确定,但仍然很好奇你是否在我写纸之前就已经知道答案:)【参考方案2】:

要获取此类未处理的异常,请确保您调用的是UseExceptionHandler

在下面的链接中搜索“捕获并记录未处理的异常”

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-5.0

在启动类中,查找函数

public void Configure

在该函数中,确保您调用了UseExceptionHandler,如下所示,如文档中所述。

if (env.IsDevelopment())

    app.UseDeveloperExceptionPage();

else

    app.UseExceptionHandler("/Error");
    app.UseHsts();

【讨论】:

这不起作用,应用程序在没有运行这些异常的情况下崩溃,只是测试了一下。 ://

以上是关于Asp.net Core 如何记录 System.AccessViolationException的主要内容,如果未能解决你的问题,请参考以下文章

我如何在 ASP.Net Core 2.1 mvc 应用程序中包含 System.Identitymodel 4.0

ASP.NET Core 3.0 System.Text.Json骆驼案例序列化

在带有数据库的 ASP.NET Core 5.0 应用程序中使用 Serilog 实现日志记录

在 ASP.NET Core 6 中,为啥 System.Private.ServiceModel.resources.dll 的已发布输出中需要语言文件夹以及如何消除它们?

如何使用 ASP.NET Core 更新由依赖表组成的记录 [关闭]

ASP.NET Core 6 Web API 的集成测试引发 System.InvalidOperationException