記一次 .NET 某企業 ERP網站系統 崩潰分析

来源:https://www.cnblogs.com/huangxincheng/archive/2023/03/27/17260332.html
-Advertisement-
Play Games

一:背景 1. 講故事 前段時間收到了一個朋友的求助,說他的ERP網站系統會出現偶發性崩潰,找了好久也沒找到是什麼原因,讓我幫忙看下,其實崩潰好說,用 procdump 自動抓一個就好,拿到 dump 之後,接下來就是一頓分析了。 二:WinDbg 分析 1. 是什麼導致的崩潰 windbg 有一個 ...


一:背景

1. 講故事

前段時間收到了一個朋友的求助,說他的ERP網站系統會出現偶發性崩潰,找了好久也沒找到是什麼原因,讓我幫忙看下,其實崩潰好說,用 procdump 自動抓一個就好,拿到 dump 之後,接下來就是一頓分析了。

二:WinDbg 分析

1. 是什麼導致的崩潰

windbg 有一個自動化的分析命令 !analyze -v 可以幫我們提前預診一下,就好像進醫院先在問詢台那裡過一下。


0:019> !analyze -v
CONTEXT:  (.ecxr)
eax=14c9cd00 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=14c9d664
eip=682a024a esp=14c9cfd4 ebp=14c9d018 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
msvcr90!fprintf+0x34:
682a024a 83c414          add     esp,14h
Resetting default scope

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 682a024a (msvcr90!fprintf+0x00000034)
   ExceptionCode: c0000417
  ExceptionFlags: 00000001
NumberParameters: 0

PROCESS_NAME:  w3wp.exe

ERROR_CODE: (NTSTATUS) 0xc0000417 -    C

EXCEPTION_CODE_STR:  c0000417

STACK_TEXT:  
14c9d018 1766013b     00000000 176d9c60 17def1a8 msvcr90!fprintf+0x34
WARNING: Stack unwind information not available. Following frames may be wrong.
14c9d664 454c5153     75636578 203a6574 5332347b satrda!Writer_Write+0x4bb
000000c8 75636578     203a6574 5332347b 207d3230 0x454c5153
000000c8 17673623     17d538e8 17ded730 00000001 crypt32!profapi_NULL_THUNK_DATA_DLA <PERF> (crypt32+0x126578)
00000009 176604b6     14c9d74c 17ded730 17dae9c8 satrda!SATRDA_Proto_UnitTest+0x6c93
ffffffff 17654012     17dae9c8 17d538e8 17ded730 satrda!Writer_Write+0x836
17dae9c8 665fe072     14c9d74c 00000001 1765405b satrda!ConfigDSN+0xd0c2
...
160a0000 00000000     00000000 00000000 00000000 0x7071e31

FAULTING_SOURCE_LINE:  f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c

FAULTING_SOURCE_FILE:  f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c

FAULTING_SOURCE_LINE_NUMBER:  55

FAULTING_SOURCE_CODE:  
No source found for 'f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c'


SYMBOL_NAME:  msvcr90!fprintf+34

MODULE_NAME: msvcr90

IMAGE_NAME:  msvcr90.dll

STACK_COMMAND:  ~19s; .ecxr ; kb

FAILURE_BUCKET_ID:  INVALID_CRUNTIME_PARAMETER_c0000417_msvcr90.dll!fprintf

從錯誤信息看,問題是出在 satrda.dll 這個第三方庫,趕緊網上搜一下是這是何方神聖。

看樣子是一個連接資料庫的商業組件,接下來看下 FAILURE_BUCKET_ID: INVALID_CRUNTIME_PARAMETER_c0000417_msvcr90.dll!fprintf 信息,可以發現因為在調用 fprintf 函數時出現了參數錯誤,到這裡我們將包圍圈極大的收縮了。

2. 為什麼會出現參數錯誤

熟悉 C 語言 fprintf 函數的朋友都知道,它是用來向 文件 寫入數據的,類似 C# 的 WriteFile,既然報了參數異常,那就說明肯定在參數上出了問題,接下來看下它的簽名。


int fprintf(
   FILE *stream,
   const char *format [,
   argument ]...
);

有了這些基礎之後切到 19 號線程觀察下它的調用棧。


0:019> ~19s; .ecxr ; kb 10
eax=14c9cd00 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=14c9d664
eip=682a024a esp=14c9cfd4 ebp=14c9d018 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
msvcr90!fprintf+0x34:
682a024a 83c414          add     esp,14h
 # ChildEBP RetAddr      Args to Child              
00 14c9d018 1766013b     00000000 176d9c60 17def1a8 msvcr90!fprintf+0x34 [f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c @ 55] 
WARNING: Stack unwind information not available. Following frames may be wrong.
01 14c9d664 454c5153     75636578 203a6574 5332347b satrda!Writer_Write+0x4bb
02 000000c8 75636578     203a6574 5332347b 207d3230 0x454c5153
03 000000c8 17673623     17d538e8 17ded730 00000001 crypt32!profapi_NULL_THUNK_DATA_DLA <PERF> (crypt32+0x126578)
04 00000009 176604b6     14c9d74c 17ded730 17dae9c8 satrda!SATRDA_Proto_UnitTest+0x6c93
05 ffffffff 17654012     17dae9c8 17d538e8 17ded730 satrda!Writer_Write+0x836
06 17dae9c8 665fe072     14c9d74c 00000001 1765405b satrda!ConfigDSN+0xd0c2
07 17ded730 63207463     2c44492e 6f532e63 632c7472 clr!CompressDebugInfo::CompressBoundariesAndVars+0x2d0
08 656c6573 2c44492e     6f532e63 632c7472 7261502e 0x63207463
09 656c6573 6f532e63     632c7472 7261502e 49746e65 0x2c44492e
0a 656c6573 69482e63     6e656464 4c2e632c 6c657665 Microsoft_Build_Tasks_v4_0_ni+0x2f2e63
0b 2c687461 6e656464     4c2e632c 6c657665 64646948 System_ServiceModel_Web_ni+0xf2e63
0c 69482e63 4c2e632c     6c657665 64646948 632c6e65 System_Runtime_Serialization_ni+0x226464
0d 6e656464 6c657665     64646948 632c6e65 6d6f432e 0x4c2e632c
0e 6e656464 64646948     632c6e65 6d6f432e 656e6f70 System_ServiceModel_ni+0x537665
0f 6c657665 632c6e65     6d6f432e 656e6f70 632c746e 0x64646948

從線程棧來看 msvcr90!fprintf 函數的第一個參數居然是 00000000 ,也就是說 *stream 這個參數為 NULL,難怪說參數異常!

3. 為什麼 stream 為空

熟悉 C 的朋友應該知道 *stream 參數是通過 fopen 函數得到的,可能有些朋友有點混,這裡就寫個簡單的模型吧。


int main()
{
	FILE* pFile;
	int n;
	char name[100];

	pFile = fopen("D:\\dumps\\myfile2.txt", "w");

	gets_s(name, 100);

	fprintf(pFile, "%s", name);

	fclose(pFile);

	return 0;
}

接下來我們到 dump 中尋找一下 fopen 函數,這個線上程棧上是沒有了,先提取出 msvcr90!fprintf+0x34 中的 RetAddr=1766013b 返回值地址到彙編視窗查找,截圖如下:

從圖中可以看到,esi 是 eax 給的,而 eax 是 call 返回值給的,不出意外 176D727Ch 中存的就是 fopen 函數,輸出如下:


0:019> u poi(176D727Ch)
msvcr90!fopen [f:\dd\vctools\crt_bld\self_x86\crt\src\fopen.c @ 123]:
682a01a2 8bff            mov     edi,edi
682a01a4 55              push    ebp
682a01a5 8bec            mov     ebp,esp
682a01a7 6a40            push    40h
682a01a9 ff750c          push    dword ptr [ebp+0Ch]
682a01ac ff7508          push    dword ptr [ebp+8]
682a01af e825ffffff      call    msvcr90!_fsopen (682a00d9)
682a01b4 83c40c          add     esp,0Ch

接下來我們需要提取 fopen 中的兩個參數,截圖如下:

第二個參數很好獲取就是 176D9C60h 的 ascii 表示,第一個參數獲取起來就麻煩了,我們需要詳細的如圖那樣推測當時的 esp 指向的位置。


0:019> da poi(14c9d02c+0x5c)
17def0e0  "log/20220810.txt"
0:019> da 176D9C64h
176d9c64  "at++"

還原成 C 代碼大概就是:


FILE*  pFile = fopen("log/20220810.txt", "at++");

代碼大概是恢復出來了,那為什麼會拋異常呢? windbg 有一個 !gle 命令可以查看當時發生了什麼錯誤。


0:019> !gle
LastErrorValue: (NTSTATUS) 0 (0) - STATUS_SUCCESS
LastStatusValue: (NTSTATUS) 0xc000003a - {            }       %hs

接下來到微軟的官方文檔:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 找一下這個 3a 到底表示啥意思,截圖如下:

從圖中看,原來是路徑不存在的錯誤,應該就是沒找到 20220810.txt 這個文件。

到這裡就基本弄清楚了來龍去脈,應該是朋友的伺服器有意或者無意清理了由 satrda 生成的20220810.txt文件,引發 satrda.dll 找不到文件路徑導致的程式崩潰,將這些信息提供給朋友之後,讓朋友去找 satrda 官網去瞭解下詳情,畢竟官方纔是最清楚的。

三:總結

這次事故是由於 satrda 層面找不到文件路徑導致的程式崩潰,據朋友說在 C# 層面沒收到這種C++異常,確實當 C# 和 C++ 產生交互時經常會有各種奇怪的問題,我無意刪除你的,你無意干擾我的,大家都好自為之吧

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基於.NET Core + Jquery實現文件斷點分片上傳 前言 該項目是基於.NET Core 和 Jquery實現的文件分片上傳,沒有經過測試,因為博主沒有那麼大的文件去測試,目前上傳2G左右的文件是沒有問題的。 使用到的技術 Redis緩存技術 Jquery ajax請求技術 為什麼要用到R ...
  • 1. 重寫和覆蓋的定義 1.1 重寫(override)的定義 在C#中,用override關鍵字來重寫一個父類中的虛方法或抽象方法。override關鍵字用於指示編譯器,我要用派生類中的一個方法,重寫基類中的同名方法。通過重寫基類中的方法,可以實現多態性。有關重寫與虛方法和抽象方法的詳細示例,可移 ...
  • 1. 多態性定義 C#中的多態性是OOP(面向對象編程)的一個基本概念,它允許一個對象在不同情況下表現出不同的行為,以增強代碼的可重用性和靈活性。 根據網上的教程,我們得知C#多態性分為兩類,靜態和動態。但實際上,C#沒有嚴格的靜態和動態多態性的分法。之所以這麼分,還是為了我們便於理解,我們沿用這個 ...
  • 1. 抽象方法與虛方法的區別 先說兩者最大的區別:抽象方法是需要子類去實現的。虛方法是已經實現了的,可以被子類覆蓋,也可以不覆蓋,取決於需求。因為抽象類無法實例化,所以抽象方法沒有辦法被調用,也就是說抽象方法永遠不可能被實現。 如果需要瞭解虛方法及抽象方法具體的定義和語句,請移步:C#多態性學習,虛 ...
  • 前段時間小編同事面試遇到了這個問題,由於同事比較菜並未很完美的完成這個問題,本文就替小編來解答一下。在C#中有多種方式類遍歷指定文件夾中的文件,本文將介紹三種方式。 一、使用Directory類的GetFiles方法: 示例代碼如下: string[] files = Directory.GetFi ...
  • PDF/A是一種ISO標準的PDF文件格式版本,是為長期保存文件而設計的。它提供了一種工具,使電子文件在長時間之後依然以一種保留其外觀的方式重現,而不管該文件是用什麼工具和系統創建、儲存或製作的。這種保留方式使PDF文件可自我持續。PDF/A通過嵌入在文檔自身內部顯示該文檔的信息(內容、顏色、字體、 ...
  • 本文屬於OData系列 目錄 武裝你的WEBAPI-OData入門 武裝你的WEBAPI-OData便捷查詢 武裝你的WEBAPI-OData分頁查詢 武裝你的WEBAPI-OData資源更新Delta 武裝你的WEBAPI-OData之EDM 武裝你的WEBAPI-OData常見問題 武裝你的WE ...
  • 一、前言 在最近的項目開發中,涉及到瞭解析DICOM文件。根據百度百科可知,DICOM(Digital Imaging and Communications in Medicine)即醫學數字成像和通信,是醫學圖像和相關信息的國際標準(ISO 12052)。它定義了質量能滿足臨床需要的可用於數據交換 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...