Linux 上的 .NET 崩潰了怎麼抓 Dump

来源:https://www.cnblogs.com/huangxincheng/archive/2023/05/29/17440153.html
-Advertisement-
Play Games

## 一:背景 ### 1. 講故事 訓練營中有朋友問在 Linux 上如何抓 crash dump,在我的系列文章中演示的大多是在 Windows 平臺上,這也沒辦法要跟著市場走,誰讓 .NET 的主戰場在**工控** 和 **醫療** 呢,上一張在 合肥 分享時的一個統計圖。 ![](https ...


一:背景

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 的方式:前者適合非托管程式,後者適合托管程式,相信這篇文章能極大的節省各方的溝通成本,花點時間整理下很值。

圖片名稱
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Winform中通過自帶的App.config實現從配置文件中讀取配置 場景 Winform中實現保存配置到文件/項目啟動時從文件中讀取配置(序列化與反序列化對象): Winform中實現保存配置到文件/項目啟動時從文件中讀取配置(序列化與反序列化對象)_winform 讀取配置文件_霸道流氓氣質的 ...
  • # 什麼是線程 Thread - 線程是一個可執行路徑,它可以獨立於其它線程執行。 - 每個線程都在操作系統的進程(Process)內執行,而操作系統進程提供了程式運行的獨立環境。 - 單線程應用,在進程的獨立環境里只跑一個線程,所以該線程擁有獨占權 - 多線程應用,單個進程中會跑多個線程,它們會共 ...
  • 1. 函數(方法)的簡介 函數,在C# 中更多的被稱為方法。它表示一個的類所具有的行為(方法,函數)。 方法的作用 封裝一些公共的代碼,以達到功能重覆利用,減少代碼冗餘。例如,我們經常要進行 輸入,輸出,系統於是幫我們封裝好了 Console.WriteLine(), Console.ReadLin ...
  • 指的是從一種類型,轉換為另外一種類型。例如:“123” 字元串 可以轉換為 整形 123。 類型轉換分為:強制轉換 (顯示轉換)與 隱式轉換 按記憶體分類:裝箱,拆箱 1. 隱式轉換 對於內置數值類型,如果要存儲的值無需截斷或四捨五入即可適應變數,則可以進行隱式轉換。 對於整型類型,這意味著源類型的範 ...
  • 1. 註釋 不寫註釋的程式員都是耍流氓!!名字瞎起是更是土匪!!! 1. 單行文本註釋 static void Main(string[] args) { // 這是單行文本註釋,向控制台輸出一段字元串 Console.WriteLine("Hello World!"); Console.ReadL ...
  • 第一單元 .Net 平臺介紹 學習編程,電腦基本配置(當然配置越高越好): 記憶體 :初期學習8 G,後期可能跟不上, 最好16 G以上 硬碟:500 G,5400 轉速,至少C盤是固態,全是固態最好 顯卡:2 G, 最好是獨顯 解析度:1920 * 1080 CPU 4核以上,i 5 可能已經跟不上 ...
  • # 使用Unity Console視窗的LogEntries私有類實現自定義日誌系統 在Unity開發過程中,我們經常需要使用Console視窗來查看程式運行時的日誌信息。Unity內置的日誌系統提供了基本的日誌功能,但有時我們需要更多的自定義選項。本文將介紹如何使用Unity Console視窗的 ...
  • 在學習或者日常工作中,有時我們需要把幻燈片的東西整理成文字,而從 PowerPoint 演示文稿中一張一張的整理手動複製粘貼,整個過程會非常費精力且耗時。那麼怎麼樣才能比較輕鬆且快速地提取PowerPoint中的文字呢?今天這篇文章就將為你介紹如何通過編程方式提取PowerPoint中的文字,文章最 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...