Linux 上的 .NET 崩溃了怎么抓 Dump

news2024/12/27 13:15:00

一:背景

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 的方式:前者适合非托管程序,后者适合托管程序,相信这篇文章能极大的节省各方的沟通成本,花点时间整理下很值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/583143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity3D:项目 ID 不匹配的情况下如何应对

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 如果在 Services 窗口的 Settings 中找不到项目 ID&#xff0c;或者如果发现项目 ID 不匹配&#xff0c;这可能是因为使用了较早版本的 Unity 来升级项目&#xff0c;或在脱机时创建…

Win10电脑应用程序并行配置不正确怎么办?

Win10电脑应用程序并行配置不正确怎么办&#xff1f;有用户在运行某些软件时&#xff0c;突然提示出错信息“应用程序无法启动&#xff0c;因为应用程序的并行配置不正确&#xff0c;出现这一问题可能是禁用本地相关服务&#xff0c;或者新安装的系统缺少必要的VC 运行。那么具…

PTQ-PDPMV1 PROSOFT DP主网络接口模块

Quantum的PROFIBUS DP主网络接口模块 PTQ-PDPMV1 PROFIBUS DP主网络接口允许Quantum处理器与支持PROFIBUS DP V0或V1的从设备轻松连接。该模块作为PROFIBUS网络和处理器之间的输入/输出模块。PROFIBUS是工业自动化中最常用的协议之一。应用领域包括电力和配电、石化、水和天然…

基于stm32mp157 linux开发板ARM裸机开发教程7:Cortex-A7 GPIO 实验(连载中)

前言&#xff1a; 目前针对ARM Cortex-A7裸机开发文档及视频进行了二次升级持续更新中&#xff0c;使其内容更加丰富&#xff0c;讲解更加细致&#xff0c;全文所使用的开发平台均为华清远见FS-MP1A开发板&#xff08;STM32MP157开发板&#xff09; 针对对FS-MP1A开发板&…

如何在命令行编译运行java程序?

2023年5月29日&#xff0c;周一下午&#xff1a; 好久没写java程序了&#xff0c;今天居然忘了怎么用命令行编译运行java程序了&#xff0c;还好后来想起来了&#xff0c;为了避免忘记&#xff0c;写篇博客记录一下 1、先用记事本等编辑器写一个java程序&#xff0c;文件名要和…

网络货运系统源码 网络货运平台源码,货运APP源码 货物运输管理源码

网络货运系统源码 网络货运平台源码&#xff0c;货运APP源码 货物运输管理源码 网络货运为无车承运人更名而来&#xff0c;网络货运平台的好处可以节省找车找货的时间与成本。根据国家对智慧物流行业的发展规划&#xff0c;及《网络平台道路货物运输经营管理办法》等相关法律法…

github创建仓库和拉取代码

目录 一、git创建仓库 第一步&#xff1a;首先登录github 第二步&#xff1a;进入建立的仓库(或者新建仓库) 第三步&#xff1a;创建成功 第四步&#xff1a;在本地新建一个文件夹&#xff0c;然后在文件夹下打开git bash 第五步&#xff1a;在git bash命令框执行git init…

Linux:centos:修改临时ip永久ip

使用 ifconfig 查看网卡信息以及ip 临时配置ip 找到要修改ip的网卡的名称&#xff08;我这里使用名称为&#xff1a;ens33网卡&#xff09; # ifconfig 网卡名 ip /子网掩码 ifconfig ens33 192.168.1.2/24 配置永久ip 去配置网卡文件 vi /vim 或 nano vim /etc/s…

腾讯云轻量服务器和云服务器区别(超详细全解析)

腾讯云轻量服务器和云服务器有什么区别&#xff1f;为什么轻量应用服务器成本低&#xff1f;是因为轻量服务器CPU内存性能比云服务器CVM性能差吗&#xff1f;轻量应用服务器适合中小企业或个人开发者搭建企业官网、博客论坛、微信小程序或开发测试环境&#xff0c;云服务器CVM适…

10 个对于Android开发者有用的Kotlin扩展函数#1

10 个对于Android开发者有用的Kotlin扩展函数 使用扩展函数来提高安卓开发体验 什么是扩展功能&#xff1f; Kotlin 中的扩展函数允许您向现有类添加新功能&#xff0c;而无需继承它或修改类本身。这是从类定义外部扩展类功能的便捷方式。 Log 您可以any object使用此扩展…

【ABAQUS】什么是剪切闭锁?剪切闭锁会导致什么?

“完全积分”是指当单元具有规则形状时&#xff0c;对单元刚度矩阵中的多项式项进行精确积分所需的高斯点数。对于六面体和四边形元素&#xff0c;“规则形状”意味着边缘是直的&#xff0c;并以直角相交&#xff0c;任何边缘节点都位于边缘的中点。 完全积分的线性元素在每个…

6种常见电流检测电路设计方案

电流检测电路设计方案&#xff08;一&#xff09; 低端检流电路的检流电阻串联到地&#xff08;图1&#xff09;&#xff0c;而高端检流电路的检流电阻是串联到高电压端&#xff08;图2&#xff09;。两种方法各有特点&#xff1a;低端检流方式在地线回路中增加了额外的线绕电…

正则表达式快速上手

一、推荐个正则表达式练习网站&#xff1a;regex101: build, test, and debug regexhttps://regex101.com/ 二、正则表达式常用的几个符号 &#xff08;一&#xff09;限定符 1. &#xff1f;&#xff1a; 表示匹配的字符串中&#xff0c;&#xff1f;前面的字符可有可无&a…

VUE3.0 路由跳转之后页面停留在上一个浏览页面位置不会回到顶部问题

方式一&#xff1a;普通用法&#xff0c;vue2.0也可用 // 一般方式路由拦截 export default {// 组件守护器beforeRouteEnter(to, from, next) {// A跳转到B&#xff0c;B页面停留在A页面的滚动位置&#xff1b;解决方法&#xff1a;将scrollTop设置为0window.scroll(0, 0);ne…

使用docker部署mysql的主从复制

前言&#xff1a; 客户需要数据库做一个备份&#xff0c;所以这次部署mysql的主从复制&#xff0c;由于测试原因两个mysql服务都安装在一台服务器上&#xff0c;实际部署中一般分开部署。 介绍&#xff1a; 用途&#xff1a; 实时灾备&#xff0c;用于故障切换读写分离&…

excel常用操作

1 基础操作 1.1 冻结首行 选中需要冻结的行&#xff0c;视图--冻结窗格&#xff0c;从而使其固定显示。

提权神器:WindowsVulnScan

简介 这是一款基于主机的漏洞扫描工具&#xff0c;采用多线程确保可以快速的请求数据&#xff0c;采用线程锁可以在向sqlite数据库中写入数据避免database is locked的错误&#xff0c;采用md5哈希算法确保数据不重复插入。 它可以实现自动化对目标主机操作系统信息收集&…

【开发者指南】如何在MyEclipse中使用 XML编辑器

XML编辑器包括高级XML编辑功能。通过本文&#xff0c;你将了解其编辑功能和网页XML编辑&#xff0c;一起来看看吧~ 1. Web XML编辑器 MyEclipse Web XML编辑器包括高级XML编辑功能&#xff0c;如: 语法高亮显示标签和属性内容辅助实时验证(在您输入时)文档内容的源视图、设计…

图像增强算法(直方图均衡化、拉普拉斯、Log、伽马变换)

https://www.cnblogs.com/polly333/p/7280764.html https://www.cnblogs.com/polly333/p/7280764.html https://www.cnblogs.com/polly333/p/7280764.html 一、图像增强算法原理 图像增强算法常见于对图像的亮度、对比度、饱和度、色调等进行调节&#xff0c;增加其清晰度&a…

LinuxShell编程

Shell编程 Shell的概念介绍 命令解释器 Shell是命令解释器(command interpreter)&#xff0c;是Unix操作系统的用户接口&#xff0c;程序从用户接口得到输入信息&#xff0c;shell将用户程序及其输入翻译成操作系统内核&#xff08;kernel&#xff09;能够识别的指令&#x…