前言

经常排查问题的朋友都知道,我们在遇到CPU或者内存高的时候,有时会生成dump文件来做分析。但是我们也会遇到一些场景,应用程序直接崩溃退出,这个时候我们已经没法使用常规方式dump了,因为整个进程树已经退出了,那么我们有没有办法让系统自动做dump,答案是肯定的:让系统在程序崩溃时自动创建Dump。

无论是 .net framework还是 .net core 项目,都支持应用程序崩溃时生成转储,本篇我们重点看下 .net core应用在docker、macOS(lunix类似)环境下是如何实现的。

配置

设置一些变量参数:

  • COMPlus_DbgEnableMiniDump 或 DOTNET_DbgEnableMiniDump: 如果设置为 1,则发生故障时启用CoreDump生成。默认值为:0
  • COMPlus_DbgMiniDumpType 或 DOTNET_DbgMiniDumpType: 要收集的转储类型。 有关详细信息,请看下文的说明。默认值为:2
  • COMPlus_DbgMiniDumpName 或 DOTNET_DbgMiniDumpName: 写入转储的文件路径。 确保运行 dotnet 进程的用户具有指定目录的写入权限。默认值为:/tmp/coredump.
  • COMPlus_CreateDumpDiagnostics 或 DOTNET_CreateDumpDiagnostics: 如果设置为 1,则启用转储进程的诊断日志记录。默认值为:0
  • COMPlus_EnableCrashReport 或 DOTNET_EnableCrashReport:(需要 .NET 6 或更高版本,目前仅Linux和MacOS可用)如果设为 1,运行时会生成 JSON 格式的故障报表,其中包括有关故障应用程序的线程和堆栈帧的信息。 故障报表名称是追加了 .crashreport.json 的转储路径/名称。
  • COMPlus_CreateDumpVerboseDiagnostics 或 DOTNET_CreateDumpVerboseDiagnostics:(需要 .NET 7 或更高版本)如果设为 1,则启用转储进程的详细诊断日志记录。
  • COMPlus_CreateDumpLogToFile 或 DOTNET_CreateDumpLogToFile:(需要 .NET 7 或更高版本)应写入诊断消息的文件路径。 如果未设置,则将诊断消息写入故障应用程序的控制台。

对于这些环境变量,.NET 7 标准化前缀 DOTNET_,而不是 COMPlus_。 但是,COMPlus_ 前缀仍将继续正常工作。 如果使用的是早期版本的 .NET 运行时,则环境变量仍应该使用 COMPlus_ 前缀。

关于DOTNET_DbgMiniDumpType的说明如下所示:

1: Mini 小型Dump,其中包含模块列表、线程列表、异常信息和所有堆栈。
2: Heap 大型且相对全面的Dump,其中包含模块列表、线程列表、所有堆栈、异常信息、句柄信息和除映射图像以外的所有内存。
3: Triage 与 Mini 相同,但会删除个人用户信息,如路径和密码。
4: Full 最大的转储,包含所有内存(包括模块映像)。
一般情况下,我们会配置下面的环境变量:

DOTNET_DbgEnableMiniDump = 1
DOTNET_DbgMiniDumpName = [有权限的Path目录]
DOTNET_CreateDumpDiagnostics = 1
DOTNET_EnableCrashReport = 1

用一段代码试试

由于笔者所使用的是 .net 6.0,所以这里我们先在程序启动的时候打印出前缀为COMPlus_的环境变量的值。(这一段不要省,因为很多时候,你以为设置了环境变量,但是其实没生效。)

foreach (DictionaryEntry environmentVariable in Environment.GetEnvironmentVariables())
{
if (environmentVariable.Key.ToString()?.StartsWith("COMPlus") == true)
{
Console.WriteLine($"{environmentVariable.Key}={environmentVariable.Value}");
}
}

然后我们在Thread中抛出一个异常,这会导致应用程序退出或者容器退出。

public static void Bar()
{
var thread = new Thread(() => throw new Exception("Crash"));
thread.Start();
}

配置

macOS

注意:.net5 开始才支持macOS的dump。
可以在powershell中执行命令用于测试,注意这种方式设置的环境变量仅限于当前会话中有效,设置完成后启动你的应用即可。

$env:DOTNET_DbgEnableMiniDump = 1
$env:DOTNET_DbgMiniDumpType = 4
$env:DOTNET_CreateDumpDiagnostics = 1
$env:DOTNET_EnableCrashReport = 1
$env:DOTNET_DbgMiniDumpName = "有权限的路径"

docker

容器部署,需要做以下几点:

  1. dockerfile中添加环境变量。
  2. 需要一个有写入权限的目录
  3. docker 容器中的核心转储生成需要 ptrace 功能(--cap-add=SYS_PTRACE 或 --privileged)

docker中需要把目录挂载到宿主机,否则容器退出,dump文件也会删除。

下方是一个dockerfile示例,以作参考。

FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY . /publish
WORKDIR /publish
EXPOSE 5100
ENV ASPNETCORE_URLS http://*:5100
# 设置环境变量
ENV COMPlus_DbgEnableMiniDump=1
ENV COMPlus_CreateDumpDiagnostics=1
ENV COMPlus_DbgMiniDumpType=4
ENV COMPlus_DbgMiniDumpName=/publish/dump/dumptest.dmp
ENV COMPlus_EnableCrashReport=1
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' > /etc/timezone
# 创建文件夹组给权限
RUN mkdir -p /publish/dump/ && chmod 777 /publish/dump/
CMD ["dotnet", "WebApplication7.dll"]

在创建容器时,带参数--cap-add=SYS_PTRACE使我们容器拥有相应的权限

sudo docker run --cap-add=SYS_PTRACE -d --name apitest -p 5101:5100  apitest\:v1

运行

  1. 使用docker的方式启动应用程序后,在下图中显示了环境变量的值,这说明设置是成功的。

  2. 接下来调用我们抛异常的api后,就会看到容器虽然退出了,但是dump的还是产生了,我们也可以在文件中查看生成的dump文件。

注意事项

如果你在测试的过程没有成功,检测下环境变量和所使用的版本是否对应。

参与文献

  1. https://www.cnblogs.com/InCerry/p/how_to_automic_create_dump_when_app_crash.html
  2. https://github.com/dotnet/coreclr/blob/master/Documentation/botr/xplat-minidump-generation.md#configurationpolicy

.net ocre 程序崩溃自动dump在多平台中的实现的更多相关文章

  1. c++ 程序崩溃生成Dump文件

    #include "Windows.h"#include "DbgHelp.h" int GenerateMiniDump(PEXCEPTION_POINTER ...

  2. windows程序崩溃生成dump文件

    第一种: 通过任务管理器:这种适用在程序挂了(crash)的时候进程还未退出,比如我运行程序,出现了下面的错: 此时打开任务管理器,右击相应进程,点击"Create Dump File“: ...

  3. 如何在.NET程序崩溃时自动创建Dump?

    今天在浏览张队转载文章的留言时,遇到一个读者问了这样的问题,如下图所示: 首先能明确的一点是"程序崩溃退出了是不能用常规的方式dump的",因为整个进程树都已经退出.现场已经无法使 ...

  4. .NET程序崩溃了怎么抓 Dump ? 我总结了三种方案

    一:背景 1. 讲故事 最近几天接到了几个crash的求助,可能这几个朋友没玩过怎么去生成dump,只能手把手教,感觉也不是一个办法,所以有必要总结一下,后续再有朋友咨询的话,我就可以把这篇文章丢过去 ...

  5. WinDbg抓取程序报错dump文件的方法

    程序崩溃的两种主要现象: a. 程序在运行中的时候,突然弹出错误窗口,然后点错误窗口的确定时,程序直接关闭 例如: “应用程序错误” “C++错误之类的窗口” “程序无响应” “假死”等 此种崩溃特点 ...

  6. 转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案

    原文链接: https://blog.csdn.net/u014740338/article/details/66975550 问题描述 Linux内存使用量超过阈值,使得Java应用程序无可用内存, ...

  7. Android 应用程序崩溃日志捕捉

    程序崩溃是应用迭代中不可避免的问题,即使有着5年或者10年经验的程序猿也无法完全保证自己的代码没有任何的bug导致崩溃,现在有一些第三方平台可以帮助我们搜集应用程序的崩溃,比如友盟,详情如下图 虽然能 ...

  8. 使用SetUnhandledExceptionFilter转储程序崩溃时内存DMP .

    关于程序崩溃时转储内存DMP,可以设置注册表,使程序崩溃时自动转储内存DMP,见程序崩溃时利用注册表自动转储内存DMP.本文要介绍的是使用SetUnhandledExceptionFilter函数在程 ...

  9. VEH帮你定位程序崩溃地址

    之前朋友有一个服务端程序,总是受到一些人的恶意漏洞攻击,没有源代码,只好反汇编修复了漏洞,并且使用WinLicense加保护授权. 漏洞总不是一次可以修复完的,恶意攻击并没有停止,然后加了WL保护程序 ...

  10. 记一次 .NET 某医疗器械 程序崩溃分析

    一:背景 1.讲故事 前段时间有位朋友在微信上找到我,说他的程序偶发性崩溃,让我帮忙看下怎么回事,上面给的压力比较大,对于这种偶发性崩溃,比较好的办法就是利用 AEDebug 在程序崩溃的时候自动抽一 ...

随机推荐

  1. AdGuard Home使用体验

    AdGuard Home使用体验 AdGuard Home is a network-wide software for blocking ads and tracking. After you se ...

  2. 在idea里面如何配置自己的tomcat

    第一:到官网上去下载自己电脑对应的tomcat版本 第二:下载后解压 在bin目录里面找到: 双击打开是不是会出现: 然后再在bin里面找到:shutdown.bat 双击给他关闭了 第三:在我的电脑 ...

  3. SpringBoot模板一

    SpringBoot模板一 SpringBoot员工管理系统 用到的技术: Version1 JDBC MySQL SSM thymeleaf lombok shiro WebSocket Swagg ...

  4. Element-Plus官网Header类像素效果的实现

      Element-Plus官网Header类像素效果 一.前言 在使用Element-Plus时,发现有两个很有趣的效果,一个是header的背景模糊效果,另一个是黑夜模式切换动画,在此我们先来研究 ...

  5. 一看就懂!任务提交的资源判断在Taier中的实践

    Taier 介绍 Taier 是袋鼠云开源项目之一,是一个分布式可视化的DAG任务调度系统. 旨在降低ETL开发成本.提高大数据平台稳定性,大数据开发人员可以在 Taier 直接进行业务逻辑的开发,而 ...

  6. Java源码分析系列笔记-1.JMM模型之先谈硬件

    目录 1. 冯诺依曼体系结构 2. 高速缓存 2.1. 工作原理 2.2. 存储器层次结构 2.3. 局部性原理 3. 缓存一致性/可见性问题 3.1. 如何解决 3.1.1. 总线加锁 3.1.2. ...

  7. Jit 报错TracingCheckError:ERROR: Graphs differed across invocations!

    问题描述 使用Tinynn将Pytorch转化为tflite时报错: 发生异常: TracingCheckError (note: full exception trace is shown but ...

  8. C# (Net6) HttpClient 帮助类

    public static string PostFromQueryToString(string url, string reqData) { string strUrl = new UriBuil ...

  9. C# 数字(阿拉伯数字)金额转汉字金额 人民币操作类 :转换人民币大小金额。

    /// <summary> /// 转换为人民币大写金额形式 /// </summary> /// <param name="Money">金额 ...

  10. 485转lora、232转lora

    lora物联网网关ZLAN9743可以实现RS232/485/422/以太网转 LoRa功能 是一款高性价比远距离无线通讯方案.LoRa和GPRS.4G方案相比它无需入网月租费,和Wifi.Zigbe ...