一:背景 1. 講故事 這些天有點意思,遇到的幾個程式故障都是和Windows操作系統或者第三方組件有關係,真的有點無語,今天就帶給大家一例 IIS 相關的與大家分享,這是一家國企的.NET程式,出現了崩潰急需分析。 二:WinDbg 分析 1. 為什麼會崩潰 崩潰原因相對還是好找的,雙擊dump文 ...
一:背景
1. 講故事
這些天有點意思,遇到的幾個程式故障都是和Windows操作系統或者第三方組件有關係,真的有點無語,今天就帶給大家一例 IIS 相關的與大家分享,這是一家國企的.NET程式,出現了崩潰急需分析。
二:WinDbg 分析
1. 為什麼會崩潰
崩潰原因相對還是好找的,雙擊dump文件之後錯誤信息馬上就列出來了,參考如下:
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(3950.1890): Stack overflow - code c00000fd (first/second chance not available)
For analysis of this file, run !analyze -v
eax=72ae2290 ebx=00000000 ecx=72afa1c0 edx=00000000 esi=72afa1c0 edi=01cb1d7c
eip=72afa1e6 esp=3e673000 ebp=3e673010 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
iiscore+0x1a1e6:
72afa1e6 ff15a064b172 call dword ptr [iiscore!GetProtocolManager+0x9370 (72b164a0)] ds:002b:72b164a0=72af5ab0
從卦中的 Stack overflow - code c00000fd
來看,這又是一個經典的棧溢出導致的崩潰,這裡棧溢出崩潰的原理就不說了,接下來觀察下是什麼代碼導致的,難道又是一個死迴圈嗎?
2. 到底是誰誘導的
要想找到是誰誘導的,肯定要看下頂層代碼是什麼,使用 k 0xffff
即可。
2732 3e6adcc0 72afa1f0 iiscore+0x1a1f0
2733 3e6adcd8 72afa1f0 iiscore+0x1a1f0
2734 3e6adcf0 72afa1f0 iiscore+0x1a1f0
2735 3e6add08 72afa1f0 iiscore+0x1a1f0
2736 3e6add20 72afa1f0 iiscore+0x1a1f0
2737 3e6add38 72afa1f0 iiscore+0x1a1f0
...
273e 3e6ade8c 734e8a9b webengine4!W3_MGD_HANDLER::ReadEntityBody+0x134
273f 3e6adeac 60251594 webengine4!MgdReadEntityBody+0x5b
...
2762 3e6aed0c 601fecc3 System_Web_ni+0x231941
2763 3e6aee00 601fe80f System_Web_ni+0x1decc3
2764 3e6aee28 028fe29a System_Web_ni+0x1de80f
2765 3e6aee48 72cbfa41 0x28fe29a
2766 3e6aeea8 72cbf972 clr!UM2MThunk_Wrapper+0x76
...
276a 3e6af024 7348ab83 webengine4!W3_MGD_HANDLER::ProcessNotification+0x62
276b 3e6af038 72b3bc52 webengine4!ProcessNotificationCallback+0x33
從卦象看,它的走勢大概是 托管 -> webengine4 -> iiscore
,然後就死掉了,很顯然 iiscore 是 iis 的核心組件,可以用 lmvm 觀察下。
0:087> lmvm iiscore
Browse full module list
start end module name
72ae0000 72b1f000 iiscore (export symbols) iiscore.dll
Loaded symbol image file: iiscore.dll
Image path: C:\Windows\System32\inetsrv\iiscore.dll
Image name: iiscore.dll
Browse all global symbols functions data
Timestamp: Fri Sep 8 11:04:45 2023 (64FA8F4D)
CheckSum: 00042ABA
ImageSize: 0003F000
File version: 8.5.9600.21613
Product version: 8.5.9600.21613
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0000.04b0
Information from resource tables:
CompanyName: Microsoft Corporation
ProductName: Internet Information Services
InternalName: iiscore.dll
OriginalFilename: iiscore.dll
ProductVersion: 8.5.9600.21613
FileVersion: 8.5.9600.21613 (winblue_ltsb.230907-1700)
FileDescription: IIS Web Server Core
LegalCopyright: © Microsoft Corporation. All rights reserved.
其實到這裡就有很大的好奇心,到底是什麼代碼這麼厲害,能導致底層的 iiscore 死迴圈,可以使用 !clrstack
觀察下托管棧。
0:087> !clrstack
OS Thread Id: 0x1890 (87)
Child SP IP Call Site
3e6aded4 72afa1e6 [InlinedCallFrame: 3e6aded4]
3e6aded0 60251594 DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, Byte[], Int32, Int32, Boolean, Int32 ByRef, IntPtr ByRef)
3e6aded4 60250906 [InlinedCallFrame: 3e6aded4] System.Web.Hosting.UnsafeIISMethods.MgdReadEntityBody(IntPtr, Byte[], Int32, Int32, Boolean, Int32 ByRef, IntPtr ByRef)
3e6adf28 60250906 System.Web.Hosting.IIS7WorkerRequest.ReadEntityCoreSync(Byte[], Int32, Int32)
3e6adf64 602508b9 System.Web.Hosting.IIS7WorkerRequest.ReadEntityBody(Byte[], Int32)
3e6adf74 6020dcfc System.Web.HttpRequest.GetEntireRawContent()
3e6adfa0 6020cc50 System.Web.HttpRequest.FillInFormCollection()
3e6adfdc 6020ebb6 System.Web.HttpRequest.EnsureForm()
3e6adfec 6020eb3e System.Web.HttpRequest.get_Form()
3e6adff8 2e17391e xxx.RequestFilterModule.CheckRequest()
接下來觀察托管層的 CheckRequest()
的鏈路,截圖如下:
這簡直太不可思議了,一句平常無奇的 base.Request.Form != null
代碼,居然把IIS給弄崩掉了,很顯然問題大概率不在 托管層。
3. iiscore 在執行什麼死迴圈
托管層這條路斷了之後,接下來在回頭觀察 iiscore 處的彙編代碼,截圖如下:
由於沒有 iiscore 的源代碼,也沒有做複原的必要,但不管怎麼樣,可以看到這地方確實存在著死迴圈,我們在用戶態沒法去做修補,最後看下當前系統情況。
0:087> vertarget
Windows 8.1 Version 9600 MP (8 procs) Free x86 compatible
Product: Server, suite: TerminalServer SingleUserTS
Edition build lab: 6.3.9600.18217 (winblue_ltsb.160124-0053)
Debug session time: Tue Mar 19 10:00:33.000 2024 (UTC + 8:00)
System Uptime: 46 days 1:32:14.541
Process Uptime: 0 days 19:11:55.000
Kernel time: 0 days 0:06:09.000
User time: 0 days 0:14:38.000
可以看到當前是 Windows Server 2012 R2,跑的是 IIS 8.5 ,由於 IIS 是強綁到 Windows的,所以能給到的建議就是:
- 使用
SFC /SCANNOW
檢修下系統文件,這是某軟 CSS 的那幫人最喜歡用的命令 O(∩_∩)O - 升級操作系統,提升 IIS 的版本。
三:總結
有時候程式崩潰往往不是你代碼寫的爛,極有可能是底層承載的bug導致的,甚至罪魁禍首是環境中的輻射,所以分析崩潰類的dump也挺玄學的,以後程式出問題第一時間不要大包大攬的往自己身上背,找出問題才是關鍵。