Linux 上的 .NET 崩溃了怎么抓 Dump
一:背景
1. 讲故事
训练营中有朋友问在 Linux 上如何抓 crash dump,在我的系列文章中演示的大多是在 Windows 平台上,这也没办法要跟着市场走,谁让 .NET 的主战场在工控 和 医疗 呢,上一张在 合肥 分享时的一个统计图。

这就导致总有零星的朋友问 Linux 平台上如何生成 crash dump,这一篇就来整理下来减少后续的沟通成本。
二:如何生成
1. 案例代码
为了方便演示,写了一段简单的 C# 代码,故意抛异常让程序崩溃。
static void Main(string[] args)
{
throw new Exception("OutOfMemory");
Console.ReadLine();
}
2. 操作系统层面捕获
一般来说操作系统层面都支持当一个进程异常退出时自动捕获Crash Dump,Linux 如此,Windows 也如此,当然默认是不支持的,需要用 ulimit 开启,这个命令可以用来配置当前系统资源的使用额度,用 limit -a 观察。
[root@localhost data]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 14950
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 14950
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
卦中的 core file size 就是用来指定生成 dump 文件的大小,默认为 0,即表示不生成,我们可以将其改成 unlimited ,即不限文件大小。
[root@localhost data]# ulimit -c unlimited
如果你想永久保存,可以修改环境变量文件 /etc/profile, 在末尾新增 ulimit -c unlimited 即可。
[root@localhost data]# vim /etc/profile
[root@localhost data]# source /etc/profile

接下来将程序在 CentOS7 上跑起来,从输出看马上就产生了崩溃文件,默认在应用程序目录下。
[root@localhost data]# dotnet Example_1_1.dll
hello world!
Unhandled exception. System.Exception: OutOfMemory
at Example_1_1.Program.Main(String[] args) in D:\skyfly\1.20230528\src\Example\Example_1_1\Program.cs:line 13
Aborted (core dumped)
[root@localhost data]# ls
core.39653 Example_1_1.deps.json Example_1_1.pdb
Example_1_1 Example_1_1.dll Example_1_1.runtimeconfig.json
core.39653 生成好了之后,可以 copy 到 Windows 平台上使用 windbg 分析,这里有一点要注意,linux 上的 dump,windbg 默认不自动加载 sos 的,需要你手工 .load 一下。
0:000> .load C:\Users\Administrator\.dotnet\sos64\sos.dll
0:000> !t
ThreadCount: 3
UnstartedThread: 0
BackgroundThread: 2
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
0 1 9ae5 000055DF29280340 20020 Preemptive 00007F352C01EE20:00007F352C01FFD0 000055df29267810 -00001 Ukn <Invalid Object> (00007f352c0138c8)
7 2 9aea 000055DF2928D990 21220 Preemptive 0000000000000000:0000000000000000 000055df29267810 -00001 Ukn (Finalizer)
1 3 9aeb 000055DF292B99E0 21220 Preemptive 0000000000000000:0000000000000000 000055df29267810 -00001 Ukn
0:000> !pe
Exception object: 00007f352c0138c8
Exception type: <Unknown>
Message: OutOfMemory
InnerException: <none>
StackTrace (generated):
SP IP Function
00007FFE584563C0 00007F3561BE2E86 Example_1_1.dll!Unknown+0x96
StackTraceString: <none>
HResult: 80131500
从卦中看,虽然异常信息有,但看不到默认的托管函数名 Main,而是用 Unknown 替代的,这就比较尴尬了,毕竟 Linux 不是微软弄的,很多地方水土不服。
可这是无数 Linux 人及官方首推生成 crash dump 的方式,在 .netcore 上总会有这样和那样的问题,那怎么办呢?问题总得要解决,针对这种场景,微软巧用开机启动的 dotnet 进程为载体,在程序崩溃的时候通过读取 环境变量 的方式来生成 crash dump。
[root@localhost ~]# ps -ef | grep dotnet
root 6566 6520 0 12:06 pts/2 00:00:00 grep --color=auto dotnet
3. 使用 dotnet 环境变量捕获
微软的 MSDN:https://learn.microsoft.com/en-us/dotnet/core/diagnostics/collect-dumps-crash 上详细的记录了如何通过读取环境变量来生成 crash dump。
大体分如下三个参数:
COMPlus_DbgEnableMiniDump
COMPlus_DbgMiniDumpType
COMPlus_DbgMiniDumpName
看到这三个变量,我敢断定它是借助了 Windows WER 生成 crash dump 的思想,不过载体不一样,前者是 dontet父进程,后者是 wer系统服务。

接下来将这三个变量配置到环境变量文件中,然后把程序跑起来了,参考如下:

[root@localhost data]# vim /etc/profile
[root@localhost data]# source /etc/profile
[root@localhost data]# dotnet Example_1_1.dll
hello world!
Unhandled exception. System.Exception: OutOfMemory
at Example_1_1.Program.Main(String[] args) in D:\skyfly\1.20230528\src\Example\Example_1_1\Program.cs:line 13
[createdump] Gathering state for process 40422 dotnet
[createdump] Crashing thread 9de6 signal 6 (0006)
[createdump] Writing full dump to file /data2/coredump.dmp
[createdump] Written 119734272 bytes (29232 pages) to core file
[createdump] Target process is alive
[createdump] Dump successfully written
Aborted (core dumped)
[root@localhost data]# cd /data2 ; ls
coredump.dmp
有了这个 coredump.dmp 之后,再把它拖到 windbg 中观察。
0:000> .load C:\Users\Administrator\.dotnet\sos64\sos.dll
0:000> !t
ThreadCount: 3
UnstartedThread: 0
BackgroundThread: 2
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
DBG ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
0 1 9de6 00005603DBF7C520 20020 Preemptive 00007FF13801EE20:00007FF13801FFD0 00005603dbf639f0 -00001 Ukn System.Exception 00007ff1380138c8
5 2 9deb 00005603DBF89B70 21220 Preemptive 0000000000000000:0000000000000000 00005603dbf639f0 -00001 Ukn (Finalizer)
6 3 9dec 00005603DBFB5C50 21220 Preemptive 0000000000000000:0000000000000000 00005603dbf639f0 -00001 Ukn
0:000> !pe
Exception object: 00007ff1380138c8
Exception type: System.Exception
Message: OutOfMemory
InnerException: <none>
StackTrace (generated):
SP IP Function
00007FFC7A324A10 00007FF16F852E86 Example_1_1!Example_1_1.Program.Main(System.String[])+0x96
StackTraceString: <none>
HResult: 80131500
从卦中看,这次终于有了,不容易,所以在 Linux 平台上,首推环境变量的模式,如果你对 coredump 的名字有自定义要求,也可以修改根据下图中的模板参数修改。

export COMPlus_DbgEnableMiniDump=1
export COMPlus_DbgMiniDumpType=4
export COMPlus_DbgMiniDumpName=/data2/%p-%e-%h-%t.dmp
[root@localhost data2]# ls
41758-dotnet-localhost.localdomain-1685332206.dmp
三:总结
这篇大概介绍了两个抓 dump 的方式:前者适合非托管程序,后者适合托管程序,相信这篇文章能极大的节省各方的沟通成本,花点时间整理下很值。

Linux 上的 .NET 崩溃了怎么抓 Dump的更多相关文章
- .NET程序崩溃了怎么抓 Dump ? 我总结了三种方案
一:背景 1. 讲故事 最近几天接到了几个crash的求助,可能这几个朋友没玩过怎么去生成dump,只能手把手教,感觉也不是一个办法,所以有必要总结一下,后续再有朋友咨询的话,我就可以把这篇文章丢过去 ...
- IEEE802.11数据帧在Linux上的抓取
IEEE802.11数据帧在Linux上的抓取终于得到了梦寐的<802.11无线网络权威指南>,虽然是复印版本,看起来也一样舒服,光看书是不行的,关键还是自己练习,这就需要搭建一个舒服的实 ...
- 怎么在Linux上抓包分析
怎么在Linux上抓包分析 1.在Linux上抓包 例如在Ubuntu上,用命令抓包, tcpdump tcp -i any -s0 -w desk.cap 用 sz desk.cap 把数据包 ...
- 利用wireshark抓取远程linux上的数据包
原文发表在我的博客主页,转载请注明出处. 前言 因为出差,前后准备总结了一周多,所以博客有所搁置.出差真是累人的活计,不过确实可以学习到很多东西,跟着老板学习做人,学习交流的技巧.入正题~ wires ...
- 记在Linux上定位后台服务偶发崩溃的问题
问题描述 在最近的后台服务中,新增将某个指令的请求数据落盘保存的功能.在具体实现时,采用成员变量来保存请求消息代理头,在接收响应以及消息管理类释放时进行销毁.测试反馈,该服务偶发崩溃. 问题分析 测试 ...
- 在 Linux 上配置一个 syslog 服务器
syslog服务器可以用作一个网络中的日志监控中心,所有能够通过网络来发送日志的设施(包含了Linux或Windows服务器,路由器,交换机以及其他主机)都可以把日志发送给它. 通过设置一个syslo ...
- IIS崩溃时自动抓取Dump
背景:在客户现场,IIS有时会崩溃,开发环境没法重现这个bug,唯有抓取IIS的崩溃是的Dump文件分析. IIS崩溃时自动抓取Dump,需要满足下面几个条件 1.启动 Windows Error R ...
- 在Linux上使用的10种云备份方案
导读 不久前,为用户提供一种备份远程机器上数据的简易方法还很稀奇.现在,我们已觉得这理所当然.Dropbox及其他公司简化了这项任务.苹果.谷歌和微软都提供各自的数据备份方法. 在Linux上,情况有 ...
- Linux上配置Nginx+PHP5(FastCGI)
原为地址:http://www.laruence.com/2009/07/28/1030.html Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,以事件驱动的方式编写,所以有非常好的性能,同时 ...
- linux上redis安装配置及其防漏洞配置及其攻击方法
Linux上redis安装: 需先在服务器上安装yum(虚拟机可使用挂载的方式安装) 安装配置所需要的环境运行指令: yum -y install gcc 进入解压文件执行make 指令进行编译 执 ...
随机推荐
- [Python]语音识别媒体中的音频到文本
@ 目录 准备工作 视频转音频 识别音频到文本 音频直接转换文本 准备工作 安装python3环境 申请一个可用的语音转换API,此篇以Microsoft Azure Speech为例 在Micros ...
- AOP的九点核心概念和作用
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点 ...
- MyBatis 版本升级引发的线上问题
MyBatis上线前后的版本:上线前(3.2.3)上线后(3.4.6) 服务上线后,开始陆续出现了一些更新系统交互日志方面的报警,这属于系统的辅助流程,报警如下代码所示.我们发现都是跟 MyBatis ...
- fluter usage---->动态更换Theme
应用中切换深色主题和暗色主题是比较常见的操作,今天我们就来学习一下Flutter中动态的切换主题. Simple Theme import 'package:flutter/material.dart ...
- DevOps|研发效能价值如何衡量
现在很多公司都在做或者计划做研发效能,也知道研发效能工作很重要,能提高产研运同学的协同效率,提高员工的工作效率和质量,提高业务交付效率和交付质量,但是价值有多大?效率又有多高呢?因为不容易说清楚,所以 ...
- 如何将 CentOS 8 转换为 CentOS Stream
CentOS 未来是不会更新数字版本了.CentOS 项目组,未来会变更为Stream版本,也就是俗称的滚动版本,那么如何将数字版本升级为滚动版本呢? 若需要将其转换为滚动版本,那么即可参考本文进行升 ...
- 搭建DHCP服务,实现自动分配地址
DHCP实现原理 DHCP定义 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作.它是一种流行的Clien ...
- ILLA Cloud: 调用 Hugging Face Inference Endpoints,开启大模型世界之门
一个月前,我们 宣布了与 ILLA Cloud 与达成的合作,ILLA Cloud 正式支持集成 Hugging Face Hub 上的 AI 模型库和其他相关功能. 今天,我们为大家带来 ILLA ...
- XSS的攻击
https://blog.csdn.net/m0_55854679/article/details/123028852
- flex:1的情况下,overflow:auto没有生效的问题
flex:1的元素的父元素必须保证高度或者宽度有具体的数值:如果父元素的高度或者宽度也是flex:1自适应的,最好在父元素上也设置overflow:auto,这样子元素的overflow:auto生效 ...