dotnet 調試應用啟動閃退的方法

来源:https://www.cnblogs.com/lindexi/archive/2022/06/20/16394515.html
-Advertisement-
Play Games

在我國自動化控制領域應用較廣泛的工業自動化組態軟體有Wonderware公司InTouch、西門子公司Wincc、GE公司iFix。國內也有一些傳統組態軟體廠商,使用的功能和形式基本上十分類似,受當時開發環境和組態軟體框架的限制,也很難做較大的改變。 ...


應用程式如果啟動即閃退,那大部分時候日誌模塊還沒初始化完成,很難通過應用自身的啟動流程瞭解到應用啟動失敗的原因。本文來告訴幾個不同的方法用來調查應用啟動失敗的原因

應用啟動失敗的原因可能有很多,例如系統環境問題,例如寫個點逗比代碼,例如調用某個帶毒的庫。如果應用啟動失敗,可以在開發環境上復現,那無疑是十分好的事情,因為咱可以使用開發環境強大的 VisualStudio 調試工具進行調試

使用 VisualStudio 調試應用啟動失敗

在有符號的配合下,使用 VisualStudio 定位應用軟體啟動失敗在大多數時候都是比較輕鬆的。當然,沒有符號的話,也沒多少問題,至少可以快速定位到是哪個模塊

使用 VisualStudio 定位應用軟體啟動失敗的方法是讓 VisualStudio 啟動應用且進入調試模式。做法就是隨便找一個 dotnet 6 的項目,當然,如果是所要調試的應用的對應版本的代碼的項目那是最好的。點擊設置調試屬性,設置應用作為啟動路徑

在 VisualStudio 2022 下,打開設置調試屬性的界面可以是在項目上進行右擊,然後點擊屬性,找到調試頁面,點擊打開調試啟動配置文件即可看到,如下圖

接著點擊創建新配置文件,選擇可執行文件

接下來選擇需要調試啟動失敗的應用的路徑

為了同時捕獲一些本機異常,還請勾選“啟用本機代碼調試”也就是混合調試模式。本機異常包括 Window Runtime 拋出的異常,基礎的 Win32 調用包含的非返回值的錯誤的異常,以及外部 C++ 等庫的異常等

為了提升調試的成功率,還請在 VisualStudio 設置裡面,將所有的異常都打開進行捕獲,同時關閉僅我的代碼調試。打開所有異常捕獲的方法是在 調試->視窗->異常設置 裡面進行配置。簡單來說就是將能打鉤的全部打上,當然,你要是熟悉的話,那就少打鉤一些咯,反正多打鉤也沒啥問題

關閉僅我的代碼可以讓你調試到一些被優化的代碼。在咱 dotnet 的程式集裡面,對 Debug 下和 Release 下最大的不同在於勾選了優化代碼。如果勾選了僅我的代碼調試,那將只調試 Debug 生成的程式集,而預設忽略對 Release 的程式集的記錄。在大部分的調試下,這個模式都可以減少發佈的程式集的干擾,可以更加方便調試業務代碼。但是當前是在調試啟動失敗,啟動失敗可能是庫的鍋,需要調試發佈的程式集,推薦關閉僅我的代碼調試。關閉的方法是在 VisualStudio 的 工具-> 選項 -> 調試 裡面,去掉 啟用“僅我的代碼” 的選項

完成配置之後,在 VisualStudio 裡面,選擇剛纔創建的新配置作為啟動項進行啟動

推薦是第一次調試可以快速過,看看是不是有異常觸發,逐步去掉那些不影響啟動異常的干擾,嘗試找到導致啟動失敗的異常,即可進行快速定位

而啟動失敗還有一個隱藏的原因是寫了逗比代碼,自己退出的。那就需要自己進行調試,找到是哪個模塊退出了應用,可以在第一次調試的時候,通過輸出視窗找到應用的退出碼是多少,輔助定位邏輯。如果退出碼是一個零,那找找是不是存在 Environment.Exit(0); 類似的代碼,可以全局進行字元串查找對應的代碼。或者是 Main 函數執行完成,例如在 WPF 裡面調用了 Application.Current.Shutdown 進行退出

在開發環境上遇到應用啟動失敗,大部分時候都可以在 VisualStudio 的幫助下快速定位到為什麼啟動失敗

但是如果應用只是在用戶的設備上才失敗,那就沒那麼好玩了,接下來將告訴大家如何調試用戶端的應用啟動失敗

使用 dnSpy 調試應用啟動失敗

在用戶的設備上,如果應用啟動失敗了,如果此時應用自己的日誌模塊還沒初始化完成,那也不用慌,系統的事件查看器可能可以幫忙到你。打開系統的事件查看器,裡面也許記錄了一些應用啟動失敗的原因,例如是系統環境問題,比如是系統缺少了某個庫,或者是驅動問題。我之前很經常遇到的就是 WPF 應用啟動失敗是由顯卡驅動導致的,不過顯卡驅動問題基本上用不到多少的調試,稍微看一下就能看到了,系統的各個部分都會很奇怪

如何打開系統的事件查看器?在 Win10 下,右擊開始菜單按鈕,點擊事件查看器即可打開。打開之後,大部分時候都可以先去看 Windows 日誌裡面的應用程式的日誌,裡面也許有記錄應用的啟動失敗原因

但是有時候事件查看器記錄的也很迷,如下麵例子的啟動失敗的記錄

系統記錄了兩條相關的錯誤日誌,一條是 .NET Runtime 錯誤日誌,如下內容

Application: KajijuniLiguqujokemka.exe
CoreCLR Version: 6.0.522.21309
.NET Version: 6.0.5
Description: The process was terminated due to an internal error in the .NET Runtime at IP 00007FF9DAEBDA03 (00007FF9DACF0000) with exit code c0000005.

另一條是 Application Error 日誌,內容如下

錯誤應用程式名稱: KajijuniLiguqujokemka.exe,版本: 1.0.0.0,時間戳: 0x62571213
錯誤模塊名稱: coreclr.dll,版本: 6.0.522.21309,時間戳: 0x625708f4
異常代碼: 0xc0000005
錯誤偏移量: 0x00000000001cda03
錯誤進程 ID: 0x3814
錯誤應用程式啟動時間: 0x01d882fdfe019fc7
錯誤應用程式路徑: C:\lindexi\Code\lindexi\BeyajaydahifallChecheecaifelwarlerenel\KajijuniLiguqujokemka\bin\Debug\net6.0-windows\KajijuniLiguqujokemka.exe
錯誤模塊路徑: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.5\coreclr.dll
報告 ID: 45232171-a61e-46fa-b80b-248ad12f5fef
錯誤程式包全名: 
錯誤程式包相對應用程式 ID: 

這兩條日誌沒有能給咱很好的一個調試思路,只能說明應用確實掛了而已。不能說明是應用自己寫了逗比代碼,也不能證明是系統環境問題,也不能證明是調用庫的問題。想要瞭解為什麼,只能繼續往下進行調試

通過 dnSpy 神器可以輔助在用戶端進行調試。根本原因在於 VisualStudio 太龐大了,在用戶端安裝不太現實。但 dnSpy 是非常輕巧的,可以免安裝使用。相當於在用戶端跑一個輕巧的 VisualStudio 調試工具

支持 dotnet 6 版本的 dnSpy 下載地址請看 支持 dotnet 6 的 dnSpy 神器版本

調試的思路和上文的使用 VisuslStudio 調試的差不多,有稍微一點不同的是,需要先將要調試的 Exe 拖入到 dnSpy 中,然後點擊此 Exe 進行調試。同樣需要勾選異常等

使用 dnSpy 調試還有一個好處是,可以無須任何符號即可進行調試,十分方便

使用 ProcDump 進行 DUMP 分析

但是如果應用的啟動失敗不是每次都復現的,是概率復現的,那就不好玩了。以上兩個方法都是需要進行調試啟動的,而大家都知道,調試模式下和非調試模式下是有差別的,例如多線程執行的差別。如果剛好啟動是因為線程安全導致的問題,那麼調試下也許是復現不到的。對於不是每次都失敗的應用啟動,進行調試是非常想砸鍵盤的,有時候調試的好好的,應用就啟動成功了。有時候覺得沒問題,按下繼續,應用就啟動失敗了

或者是在用戶端,用戶有情緒了,不適合進行慢慢的調試。此時可以用到 ProcDump 工具輔助,在應用啟動時候的時候,將失敗時做一個 DUMP 文件,然後咱就可以將這個 DUMP 傳回開發的設備上慢慢進行分析

這個 ProcDump 是微軟極品工具箱的一個很有名的工具

官方下載地址: https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump

根據官方文檔可以瞭解到使用方法是在命令行使用如下參數,即可做到在應用因為異常掛掉自動捕獲 DUMP 文件

procdump.exe -e -t -w -ma <進程名>

參數的含義如下

  • -e : 當進程遇到未經處理的異常時寫入轉儲
  • -t : 進程終止時寫入轉儲。如果應用啟動失敗是自己逗比或者某個庫逗比調用了退出進程的方法,那也可以使用捕獲到
  • -w : 等待指定的進程啟動。大部分時候都是先運行 ProcDump 工具,然後再啟動應用,這樣 ProcDump 相當於監控應用啟動失敗或退出。如此即可採用 ProcDump 啟動進程調試應用啟動閃退
  • -ma : 獲取的是 Full Dump 文件,也就是包含所有內容的 DUMP 文件,雖然這個 DUMP 比較大,但是調試會根據方便。如果傳輸過程比較難,而且開發者也熟悉調試 DUMP 可以換用 -mm 命名寫入小型 DUMP 文件

假定需要調試的啟動失敗的應用是 KajijuniLiguqujokemka.exe 應用,那麼執行的命令如下

procdump.exe -e -t -w -ma KajijuniLiguqujokemka

如此即可在應用啟動閃退自動創建 DUMP 文件。創建好的 DUMP 文件可以採用 7z 工具壓縮一下再傳回開發機器,使用 7z 可以極大壓縮 DUMP 文件,因為 DUMP 文件裡面很多數據都是全 0 的

拿到 DUMP 文件之後,就需要開啟 DUMP 調試了。最簡單的 DUMP 調試是打開 VisualStudio 將 DUMP 文件拖進入,然後如開始的步驟先配置一下,然後點擊使用混合進行調試即可

核心是看調用堆棧,和局部變數視窗,找到是哪個模塊拋出異常或者退出。如果 VisualStudio 無法幫到你,那就只能換成 WinDbg 啦,不過這又是另外一個故事了

大家可以嘗試使用我放在 github 的代碼進行測試

更多請看 dotnet 代碼調試方法

博客園博客只做備份,博客發佈就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

知識共用許可協議
本作品採用知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發佈,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我[聯繫](mailto:[email protected])。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Hi,我是Mic 一個工作了4年的粉絲,在面試的時候遇到一個這樣的問題。 “介紹一下Spring IOC的工作流程” 他說回答得不是很好,希望我能幫他梳理一下。 關於這個問題,我們來看看普通人和高手的回答。 普通人: 嗯。。。。。。。。 高手: 好的,這個問題我會從幾個方面來回答。 IOC是什麼 B ...
  • 前言 大家好,歡迎來到 Crossin的編程教室 ! 今天給大家分享的這個案例是用 Python+OpenCV 實現了自動掃雷,並突破了人類的世界記錄。(當然 這不算哈) 咱們廢話不多說,先看成果~ 中級 - 0.74秒 3BV/S=60.81 相信許多人很早就知道有掃雷這麼一款經典的游(顯卡測試) ...
  • 此問題是無法做到100%場景一致性的,只能做到基本一致或者最終一致性。 推薦使用的方案 延時雙刪 原理:先進行緩存清除,再執行update,最後(延遲N秒)再執行緩存清除。(延遲N秒)的時間要大於一次寫操作的時間。 一般執行流程: 服務節點刪除 redis 主庫數據。 服務節點修改 mysql 主庫 ...
  • 大佬的理解->Java多線程(一)多線程基礎 大佬的理解->Java多線程(二)常用的實現多線程的兩種方式 1、繼承Thread類 ​ 繼承Thread必須重寫run方法,(具體業務執行方法,需要執行的業務方法,定義在此方法中),註意此方法是線程啟動後線程自動調用的; 案例 public class ...
  • 前言 還有多少人不會python的控制結構,在評論區告訴我,讓我一個個點名提問。今天,就教會你python的控制結構… 分行與縮進 分行 •一條語句占用一行 •過長的語句可以占用多行,使用\或()控制換行 •[]、{}、()可以直接跨越多行,在列表、字典、元組中需要換行的時候也可以不用添加續行符 a ...
  • 3 Skywalking源碼導入 接上文,已經學習了Skywalking的應用,接下來我們將剖析Skywalking源碼,深度學習Skywalking Agent。 3.1 源碼環境搭建 當前最新版本是8.3.0,我們首先找到8.3.0的版本,然後下載並導入到IDEA,下載地址 https://gi ...
  • 《乘風破浪的姐姐3》王心凌一騎絕塵,破收視率,多年後再次全網爆火,某音截止現在差不多3500W粉絲,五月份熱門女星排名,弔打其它所有人,不愧是我女神! 但是這個熱度,感覺她的歌曲和MV,已經離收費越來越近了,於是我連夜用Python把所有MV 和歌曲離線,今天先給大家分享MV的方法。 女神鎮樓! 話 ...
  • 序列號 序列號是序列化和反序列化的唯一標識,是一個長整型數值; 如果類中不自己定義序列號,系統會自動生成一個序列號; 當一方實體類發生改變,而調用方的序列號是不會跟著改變的,不知道對象已修改,會導致兩邊序列號不一致,反序列化失敗; 所以要求必須手動生成一個序列號; 手動生成序列號後,可以解決目標類發 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...