最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

記一次 .NET 某企業(yè)內(nèi)部系統(tǒng) 崩潰分析

2023-06-29 06:03 作者:波叔8866  | 我要投稿

一:背景

1. 講故事

前些天有位朋友找到我,說他的程序跑著跑著就崩潰了,讓我看下怎么回事,其實沒怎么回事,抓它的 crash dump 就好,具體怎么抓也是被問到的一個高頻問題,這里再補一下鏈接: [.NET程序崩潰了怎么抓 Dump ? 我總結(jié)了三種方案]?https://www.cnblogs.com/huangxincheng/p/14811953.html?,采用第二種 AEDebug 的形式抓取即可。

二:Windbg 分析

1. 崩潰原因是什么

如果dump中塞了異常,用 windbg 打開的時候會有一個提示?This dump file has an exception of interest stored in it,輸出如下:

************* Path validation summary ************** Response ? ? ? ? ? ? ? ? ? ? ? ? Time (ms) ? ? Location Deferred ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbolsSymbol search path is: SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbolsExecutable search path is: Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64 Product: Server, suite: Enterprise TerminalServer SingleUserTS Debug session time: Wed Jun 14 13:34:49.000 2023 (UTC + 8:00)System Uptime: 0 days 3:28:04.223 Process Uptime: 0 days 0:00:14.000 ................................................................ ................................................................ ...................................................... This dump file has an exception of interest stored in it. The stored exception information can be accessed via .ecxr.(9e4.bc4): Stack overflow - code c00000fd (first/second chance not available)For analysis of this file, run !analyze -v clr!SlowAllocateString+0x11: 000007fe`f9236451 48c785b0fffffffeffffff mov qword ptr [rbp-50h],0FFFFFFFFFFFFFFFEh ss:00000000`123d5fd0=0000000000000000

從卦中看當(dāng)前有一個?Stack overflow - code c00000fd?異常,說實話好久都沒看到?棧溢出?了,甚是想念,既然說棧溢出了,那就看下異常前是個啥情況,使用?.excr?即可。

0:028> .excr;k rax=00000000123d6048 rbx=00000000123d5d70 rcx=0000000000000001rdx=0000000000000001 rsi=0000000000000000 rdi=00000000123d5880 rip=000007fef9236451 rsp=00000000123d5fb0 rbp=00000000123d6020 r8=00000000ffffffff ?r9=0000000000000000 r10=00000000123d618e r11=0000000000000000 r12=0000000000000000 r13=0000000000000000r14=0000000000000000 r15=0000000000000001iopl=0 ? ? ? ? nv up ei pl nz na pe nc cs=0033 ?ss=002b ?ds=002b ?es=002b ?fs=0053 ?gs=002b ? ? ? ? ? ? efl=00010200clr!SlowAllocateString+0x11:000007fe`f9236451 48c785b0fffffffeffffff mov qword ptr [rbp-50h],0FFFFFFFFFFFFFFFEh ss:00000000`123d5fd0=0000000000000000 ?*** Stack trace for last set context - .thread/.cxr resets it # Child-SP ? ? ? ? ?RetAddr ? ? ? ? ? ? ? Call Site00 00000000`123d5fb0 000007fe`f920a5bd ? ? clr!SlowAllocateString+0x1101 00000000`123d6050 000007fe`f920a9c7 ? ? clr!StringObject::NewString+0x2502 00000000`123d6080 000007fe`f920a80d ? ? clr!Int32ToDecStr+0xdf03 00000000`123d6320 000007fe`9ab3bb72 ? ? clr!COMNumber::FormatInt32+0x10d04 00000000`123d65f0 000007fe`9ab33e04 ? ? 0x000007fe`9ab3bb7205 00000000`123d6630 000007fe`9ab3be52 ? ? 0x000007fe`9ab33e0406 00000000`123d6720 000007fe`9ab3bd2a ? ? 0x000007fe`9ab3be5207 00000000`123d6790 000007fe`9ab33e35 ? ? 0x000007fe`9ab3bd2a08 00000000`123d67f0 000007fe`9ab3be52 ? ? 0x000007fe`9ab33e3509 00000000`123d68e0 000007fe`9ab3bd2a ? ? 0x000007fe`9ab3be52 ... ff 00000000`123df860 000007fe`9ab3bd2a ? ? 0x000007fe`9ab3be52

從卦中看,當(dāng)前默認(rèn)的 255 個棧幀全部被打滿,看樣子是無限死循環(huán)了,為了能看到托管部分我們改用?!clrstack?命令。

0:028> !clrstack OS Thread Id: 0xbc4 (28) ? ? ? ?Child SP ? ? ? ? ? ? ? IP Call Site00000000123d63b8 000007fef9236451 [HelperMethodFrame_PROTECTOBJ: 00000000123d63b8] System.Number.FormatInt32(Int32, System.String, System.Globalization.NumberFormatInfo)00000000123d65f0 000007fe9ab3bb72 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[])00000000123d6630 000007fe9ab33e04 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Int64, Int64, Boolean)00000000123d6720 000007fe9ab3be52 xxx_symbol01.xxx_symbol09.xxx_symbol00(Int32, Int32)00000000123d6790 000007fe9ab3bd2a xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Boolean)00000000123d67f0 000007fe9ab33e35 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Int64, Int64, Boolean)00000000123d68e0 000007fe9ab3be52 xxx_symbol01.xxx_symbol09.xxx_symbol00(Int32, Int32)00000000123d6950 000007fe9ab3bd2a xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Boolean)00000000123d69b0 000007fe9ab33e35 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Int64, Int64, Boolean)00000000123d6aa0 000007fe9ab3be52 xxx_symbol01.xxx_symbol09.xxx_symbol00(Int32, Int32)00000000123d6b10 000007fe9ab3bd2a xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Boolean)00000000123d6b70 000007fe9ab33e35 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Int64, Int64, Boolean)00000000123d6c60 000007fe9ab3be52 xxx_symbol01.xxx_symbol09.xxx_symbol00(Int32, Int32)00000000123d6cd0 000007fe9ab3bd2a xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Boolean)00000000123d6d30 000007fe9ab33e35 xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Int64, Int64, Boolean)00000000123d6e20 000007fe9ab3be52 xxx_symbol01.xxx_symbol09.xxx_symbol00(Int32, Int32)00000000123d6e90 000007fe9ab3bd2a xxx_symbol01.xxx_symbol09.xxx_symbol00(Byte[], Boolean) ....000000001244db60 000007fe9ab31f0e xxx.PDFFile.xxx_symbol00(System.String, System.IO.Stream, Byte[])000000001244dbc0 000007fe9ab318e5 xxx.xxx.Convertxxxx(System.IO.Stream, Int32, Int32, System.Drawing.Imaging.ImageFormat, Int32)

從卦中信息看,是代碼用?Convertxxxx?調(diào)用了一個第三方庫,在這個庫中出現(xiàn)了死遞歸。

按理說不管外界給了什么參數(shù)下去,都不應(yīng)該用死遞歸的方式來呈現(xiàn),所以這類問題可以歸于 SDK 的bug,接下來我們的研究方向就是看下這個 SDK 是何方神圣?

[assembly: AssemblyCopyright("? 2008 O2 Solutions")] [assembly: AssemblyProduct("PDFxxx4NET")] [assembly: AssemblyCompany("O2 Solutions (http://www.xxx.com/)")] [assembly: AssemblyTrademark("PDFxxx4NET is a trademark of O2 Solutions")] [assembly: AllowPartiallyTrustedCallers] [assembly: AssemblyTitle("Print and convert PDF files to images.")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyDescription("Component for rendering pdf files on .NET platform")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyInformationalVersion("2.0.1")] [assembly: AssemblyKeyName("")] [assembly: AssemblyDelaySign(false)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("2.0.1.0")]

從卦中看還是 2008 年寫的?2.0.1?版本,而官網(wǎng)早已出了 2023 年版本,也就是說 15年都沒有更新,也是厲害,截圖如下:

到這里就可以給到朋友答案了,讓他看下能否把?PDFRender4NET?升級到最新版本,按理說應(yīng)該就沒有問題了。

2. 為什么會棧溢出

心細(xì)的朋友可能會有一個疑問,既然都棧溢出了,按理說異常碼應(yīng)該是?c0000005?(訪問違例),怎么會是?c00000fd?呢?

這是一個非常好的問題,要理解為什么是?c00000fd?而不是?c0000005,需要你對棧的布局有一個比較清晰的理解,為了方便講述,以當(dāng)前的 w3wp 來繪制一張圖。

畫完這張圖肯定有朋友會提幾個反對意見:

1) 線程棧不是 1M 嗎? 怎么會是 512k 呢?

這里要說的是 1M 并不是什么公理,可以在 PE 頭上隨便設(shè)定的,截圖如下:

2)PAGE_GUARD 不是 1個內(nèi)存頁嗎?

很多教科書都是按 1個內(nèi)存頁 講述的,但這也不是定死的,也可能是多個內(nèi)存頁,比如 2個,5個,要想驗證很簡單,用?!address -f:Stack?觀察下便知。

0:121> !address -f:Stack ? ? ? ?BaseAddress ? ? ?EndAddress+1 ? ? ? ?RegionSize ? ? Type ? ? ? State ? ? ? ? ? ? ? ? Protect ? ? ? ? ? ? Usage -------------------------------------------------------------------------------------------------------------------------- ? ? ? 0`001f0000 ? ? ? ?0`00266000 ? ? ? ?0`00076000 MEM_PRIVATE MEM_RESERVE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Stack ? ? ?[~0; 9e4.e30] ? ? ? 0`00266000 ? ? ? ?0`00268000 ? ? ? ?0`00002000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE | PAGE_GUARD ? ? ? ?Stack ? ? ?[~0; 9e4.e30] ? ? ? 0`00268000 ? ? ? ?0`00270000 ? ? ? ?0`00008000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~0; 9e4.e30] ? ? ? ... ? ? ? 0`15710000 ? ? ? ?0`15788000 ? ? ? ?0`00078000 MEM_PRIVATE MEM_RESERVE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Stack ? ? ?[~139; 9e4.14ac] ? ? ? 0`15788000 ? ? ? ?0`1578d000 ? ? ? ?0`00005000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE | PAGE_GUARD ? ? ? ?Stack ? ? ?[~139; 9e4.14ac] ? ? ? 0`1578d000 ? ? ? ?0`15790000 ? ? ? ?0`00003000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~139; 9e4.14ac]

接下來我們聊一下什么是?PAGE_GUARD,從名字上看就是?哨兵頁,說白一點就是 Windows 做?棧伸展?的一種系統(tǒng)機制,當(dāng) rsp 訪問到這個區(qū)域時會引發(fā)系統(tǒng)的?頁中斷?進(jìn)而 COMMIT 更多內(nèi)存頁,新的 Commit 頁會被?哨兵?侵占,同時也會讓渡 RSP 所占的內(nèi)存頁給程序使用,這是一種良性機制,一旦?哨兵?無法侵占更多新的 COMMIT 頁時,也就表示??臻g已經(jīng)到位了,這時候會將自身的?PAGE_GUARD?標(biāo)簽去掉,表示它的使命已完成,如果此時 RSP 訪問到了這個彌留的?哨兵區(qū)?,就會拋出?c00000fd?異常,這種異常只是表示 RSP 進(jìn)入了?哨兵區(qū),不代表??臻g?真的用完了,所以這就是不拋?c0000005?的真正原因,畫個簡圖如下:

說了這么說,如何去驗證呢?非常簡單,我們提取出?StackLimit, StackBase, RSP?即可。

0:028> r rsp rsp=00000000123d5fb00:028> !teb TEB at 000007fffff70000 ? ?ExceptionList: ? ? ? ?0000000000000000 ? ?StackBase: ? ? ? ? ? ?0000000012450000 ? ?StackLimit: ? ? ? ? ? 00000000123d10000:028> !address -f:Stack ? ? ? ?BaseAddress ? ? ?EndAddress+1 ? ? ? ?RegionSize ? ? Type ? ? ? State ? ? ? ? ? ? ? ? Protect ? ? ? ? ? ? Usage -------------------------------------------------------------------------------------------------------------------------- ? ? ? 0`123d0000 ? ? ? ?0`123d1000 ? ? ? ?0`00001000 MEM_PRIVATE MEM_RESERVE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Stack ? ? ?[~28; 9e4.bc4] ? ? ? 0`123d1000 ? ? ? ?0`12450000 ? ? ? ?0`0007f000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~28; 9e4.bc4]


記一次 .NET 某企業(yè)內(nèi)部系統(tǒng) 崩潰分析的評論 (共 條)

分享到微博請遵守國家法律
康乐县| 四子王旗| 清涧县| 卢龙县| 贵港市| 威远县| 嘉祥县| 甘洛县| 霸州市| 弥勒县| 龙里县| 田东县| 尚志市| 尉犁县| 瓦房店市| 文昌市| 汉川市| 犍为县| 兰考县| 汶上县| 榆林市| 东方市| 永丰县| 义乌市| 洛浦县| 连江县| 文昌市| 庄浪县| 南投市| 清水河县| 济南市| 武山县| 正定县| 安吉县| 龙岩市| 荆门市| 乐亭县| 玉田县| 巍山| 稷山县| 武定县|