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

linux,net,崩溃,怎么,dump · 浏览次数 : 3296

小编点评

**环境变量抓取微软的 MSDN** * `COMPlus_DbgEnableMiniDump` enable mini dump * `COMPlus_DbgMiniDumpType` specify type of mini dump * `COMPlus_DbgMiniDumpName` specify name of mini dump file * `COMPlus_DbgMiniDumpPath` specify path of mini dump file **使用 dotnet 环境变量捕获微软的 MSDN** 1. `.load` `C:\Users\Administrator\.dotnet\sos64\sos.dll` load SOS dll 2. `!tThreadCount` Get thread count 3. `!peException object` Get exception object 4. `export` environment variables **修改环境变量名称** `export COMPlus_DbgEnableMiniDump=1` `export COMPlus_DbgMiniDumpType=4` `export COMPlus_DbgMiniDumpName=/data2/%p-%e-%h-%t.dmp` `export COMPlus_DbgMiniDumpPath=/data2/%p-%e-%h-%t.dmp` **生成 coredump 文件** 1. `lscoredump.dmp` Load coredump file 2. `cd /data2 ; lscoredump.dmp` Transfer coredump to Windbg

正文

一:背景

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 上总会有这样和那样的问题,那怎么办呢?问题总得要解决,针对这种场景,微软应该是通过CLR层面截获来进行支持的,在程序崩溃的时候通过读取 环境变量 的方式来生成 crash dump。

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相似的内容:

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

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

Linux 上的 .NET 如何自主生成 Dump

## 一:背景 ### 1. 讲故事 前几天微信上有位朋友找到我,说他程序的 `线程数` 会偶发性瞬时飙高,让我看下大概是什么原因,截图如下: ![](https://img2023.cnblogs.com/blog/214741/202306/214741-20230630110439615-63

用 perfcollect 洞察 Linux 上.NET程序 CPU爆高

## 一:背景 ### 1. 讲故事 如果要分析 Linux上的 .NET程序 CPU 爆高,按以往的个性我肯定是抓个 dump 下来做事后分析,这种分析模式虽然不重但也不轻,还需要一定的底层知识,那有没有傻瓜式的 CPU 爆高分析方式呢? 相信有很多朋友知道 **B站713事件**,最终就是用 p

Docker容器共享磁盘

需求:.NET程序需要监控一个FTP上的文件变化并进行操作,在linux上使用原生目录时,不管怎么切换后台运行,总是会在一段时间运行后死掉。 方案:远程也不好debug,想了一下,干脆直接使用docker-compose运行,设置死了自动重启(restart=always)就完事了。 由于FTP与.

记一次 .NET某报关系统 非托管泄露分析

## 一:背景 ### 1. 讲故事 前段时间有位朋友找到我,说他的程序内存会出现暴涨,让我看下是怎么事情?而且还告诉我是在 Linux 环境下,说实话在Linux上分析.NET程序难度会很大,难度大的原因在于Linux上的各种开源工具主要是针对 C/C++, 和 .NET 一毛钱关系都没有,说到底

记一次 .NET某游戏币自助机后端 内存暴涨分析

一:背景 1. 讲故事 前些天有位朋友找到我,说他们的程序内存会偶发性暴涨,自己分析了下是非托管内存问题,让我帮忙看下怎么回事?哈哈,看到这个dump我还是非常有兴趣的,居然还有这种游戏币自助机类型的程序,下次去大玩家看看他们出币的机器后端是不是C#写的?由于dump是linux上的程序,刚好win

[转帖]sar —— Linux 上最为全面的系统性能分析工具之一

sar —— Linux 上最为全面的系统性能分析工具之一 https://shockerli.net/post/linux-tool-sar/ 文章目录 命令参数 常用命令 性能问题排查技巧 sar(System Activity Reporter 系统活动情况报告)是目前 Linux 上最为全面

PasteSpider的集群组件PasteCluster(让你的项目快速支持集群模式)的思路及实现(含源码)

PasteSpider是什么? 一款使用.net编写的开源的Linux容器部署助手,支持一键发布,平滑升级,自动伸缩, Key-Value配置,项目网关,环境隔离,运行报表,差量升级,私有仓库,集群部署,版本管理等! 30分钟上手,让开发也可以很容易的学会在linux上部署你得项目! [从需求角度介

[转帖]018 磁盘 IO 性能监控 / 压测工具 (sar、iotop、fio、iostat)

https://my.oschina.net/u/3113381/blog/5465063 1 sar 命令查看当前磁盘 IO 读写 sar(System Activity Reporter 系统活动情况报告)是 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:

[转帖]Linux服务器上监控网络带宽的18个常用命令

https://www.pianshen.com/article/57221534801/ nload等一些工具可以读取"proc/net/dev"文件,以获得流量统计信息;而一些工具使用pcap库来捕获所有数据包,然后计算总数据量,从而估计流量负载。下面是按功能划分的命令名称。监控总体带宽使用――