天堂一区_新91在线_在线免费观看污污视频_99热只有精品在线观看_人人看黄色_www.97色.com

您的位置:财经>正文

记一次 .NET 某企业内部系统 崩溃分析 世界最资讯

2023-06-29 17:15:06 来源:哔哩哔哩

一:背景

1. 讲故事

前些天有位朋友找到我,说他的程序跑着跑着就崩溃了,让我看下怎么回事,其实没怎么回事,抓它的 crash dump 就好,具体怎么抓也是被问到的一个高频问题,这里再补一下链接: [.NET程序崩溃了怎么抓 Dump ? 我总结了三种方案]?/huangxincheng/p/?,采用第二种 AEDebug 的形式抓取即可。


(相关资料图)

二:Windbg 分析

1. 崩溃原因是什么

如果dump中塞了异常,用 windbg 打开的时候会有一个提示?This dump file has an exception of interest stored in it,输出如下:

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

从卦中看当前有一个?Stack overflow - code c00000fd异常,说实话好久都没看到?栈溢出了,甚是想念,既然说栈溢出了,那就看下异常前是个啥情况,使用?.excr即可。

0:028> .excr;krax=00000000123d6048 rbx=00000000123d5d70 rcx=0000000000000001rdx=0000000000000001 rsi=0000000000000000 rdi=00000000123d5880rip=000007fef9236451 rsp=00000000123d5fb0 rbp=00000000123d6020 r8=00000000ffffffff ?r9=0000000000000000 r10=00000000123d618er11=0000000000000000 r12=0000000000000000 r13=0000000000000000r14=0000000000000000 r15=0000000000000001iopl=0 ? ? ? ? nv up ei pl nz na pe nccs=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

从卦中看,当前默认的 255 个栈帧全部被打满,看样子是无限死循环了,为了能看到托管部分我们改用?!clrstack命令。

0:028> !clrstackOS Thread Id: 0xbc4 (28) ? ? ? ?Child SP ? ? ? ? ? ? ? IP Call Site00000000123d63b8 000007fef9236451 [HelperMethodFrame_PROTECTOBJ: 00000000123d63b8] (Int32, , )00000000123d65f0 000007fe9ab3bb72 xxx___symbol00(Byte[])00000000123d6630 000007fe9ab33e04 xxx___symbol00(Byte[], Int64, Int64, Boolean)00000000123d6720 000007fe9ab3be52 xxx___symbol00(Int32, Int32)00000000123d6790 000007fe9ab3bd2a xxx___symbol00(Byte[], Boolean)00000000123d67f0 000007fe9ab33e35 xxx___symbol00(Byte[], Int64, Int64, Boolean)00000000123d68e0 000007fe9ab3be52 xxx___symbol00(Int32, Int32)00000000123d6950 000007fe9ab3bd2a xxx___symbol00(Byte[], Boolean)00000000123d69b0 000007fe9ab33e35 xxx___symbol00(Byte[], Int64, Int64, Boolean)00000000123d6aa0 000007fe9ab3be52 xxx___symbol00(Int32, Int32)00000000123d6b10 000007fe9ab3bd2a xxx___symbol00(Byte[], Boolean)00000000123d6b70 000007fe9ab33e35 xxx___symbol00(Byte[], Int64, Int64, Boolean)00000000123d6c60 000007fe9ab3be52 xxx___symbol00(Int32, Int32)00000000123d6cd0 000007fe9ab3bd2a xxx___symbol00(Byte[], Boolean)00000000123d6d30 000007fe9ab33e35 xxx___symbol00(Byte[], Int64, Int64, Boolean)00000000123d6e20 000007fe9ab3be52 xxx___symbol00(Int32, Int32)00000000123d6e90 000007fe9ab3bd2a xxx___symbol00(Byte[], Boolean)....000000001244db60 000007fe9ab31f0e _symbol00(, , Byte[])000000001244dbc0 000007fe9ab318e5 (, Int32, Int32, , Int32)

从卦中信息看,是代码用?Convertxxxx调用了一个第三方库,在这个库中出现了死递归。

按理说不管外界给了什么参数下去,都不应该用死递归的方式来呈现,所以这类问题可以归于 SDK 的bug,接下来我们的研究方向就是看下这个 SDK 是何方神圣?

[assembly: AssemblyCopyright("? 2008 O2 Solutions")][assembly: AssemblyProduct("PDFxxx4NET")][assembly: AssemblyCompany("O2 Solutions (/)")][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("")][assembly: AssemblyKeyName("")][assembly: AssemblyDelaySign(false)][assembly: CompilationRelaxations(8)][assembly: AssemblyVersion("")]

从卦中看还是 2008 年写的?版本,而官网早已出了 2023 年版本,也就是说 15年都没有更新,也是厉害,截图如下:

到这里就可以给到朋友答案了,让他看下能否把?PDFRender4NET升级到最新版本,按理说应该就没有问题了。

2. 为什么会栈溢出

心细的朋友可能会有一个疑问,既然都栈溢出了,按理说异常码应该是?c0000005(访问违例),怎么会是?c00000fd呢?

这是一个非常好的问题,要理解为什么是?c00000fd而不是?c0000005,需要你对栈的布局有一个比较清晰的理解,为了方便讲述,以当前的 w3wp 来绘制一张图。

画完这张图肯定有朋友会提几个反对意见:

1) 线程栈不是 1M 吗? 怎么会是 512k 呢?

这里要说的是 1M 并不是什么公理,可以在 PE 头上随便设定的,截图如下:

2)PAGE_GUARD 不是 1个内存页吗?

很多教科书都是按 1个内存页 讲述的,但这也不是定死的,也可能是多个内存页,比如 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; ] ? ? ? 0`00266000 ? ? ? ?0`00268000 ? ? ? ?0`00002000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE | PAGE_GUARD ? ? ? ?Stack ? ? ?[~0; ] ? ? ? 0`00268000 ? ? ? ?0`00270000 ? ? ? ?0`00008000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~0; ] ? ? ? ... ? ? ? 0`15710000 ? ? ? ?0`15788000 ? ? ? ?0`00078000 MEM_PRIVATE MEM_RESERVE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Stack ? ? ?[~139; ] ? ? ? 0`15788000 ? ? ? ?0`1578d000 ? ? ? ?0`00005000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE | PAGE_GUARD ? ? ? ?Stack ? ? ?[~139; ] ? ? ? 0`1578d000 ? ? ? ?0`15790000 ? ? ? ?0`00003000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~139; ]

接下来我们聊一下什么是?PAGE_GUARD,从名字上看就是?哨兵页,说白一点就是 Windows 做?栈伸展的一种系统机制,当 rsp 访问到这个区域时会引发系统的?页中断进而 COMMIT 更多内存页,新的 Commit 页会被?哨兵侵占,同时也会让渡 RSP 所占的内存页给程序使用,这是一种良性机制,一旦?哨兵无法侵占更多新的 COMMIT 页时,也就表示栈空间已经到位了,这时候会将自身的?PAGE_GUARD标签去掉,表示它的使命已完成,如果此时 RSP 访问到了这个弥留的?哨兵区,就会抛出?c00000fd异常,这种异常只是表示 RSP 进入了?哨兵区,不代表栈空间真的用完了,所以这就是不抛?c0000005的真正原因,画个简图如下:

说了这么说,如何去验证呢?非常简单,我们提取出?StackLimit, StackBase, RSP即可。

0:028> r rsprsp=00000000123d5fb00:028> !tebTEB 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; ] ? ? ? 0`123d1000 ? ? ? ?0`12450000 ? ? ? ?0`0007f000 MEM_PRIVATE MEM_COMMIT ?PAGE_READWRITE ? ? ? ? ? ? ? ? ? ? Stack ? ? ?[~28; ]

相关新闻

主站蜘蛛池模板: 成人性做爰视频 | 久久久国产精品免费视频 | 午夜伦理影院 | 高清不卡免费一区二区三区 | 哪里可以免费看毛片 | 亚洲av极品视觉盛宴 | 日韩 国产 欧美 精品 在线 | 十八禁无码免费网站 | 韩国美女人成网站在线看看 | 一区二区三区视频观看 | 99久久99久久精品免费看子伦 | 毛片a级毛片免费观看 | 国产成人亚洲日韩欧美 | 国产日韩欧美在线观看不卡 | 精品国产一级毛片 | 国产精品久久久久久久影院 | 天天操天天干天天拍 | 日本三级高清电影全部 | 日本三级理论电影 | 国产欧美日韩a片免费软件 国产欧美日韩va另类在线播放 | 超污很黄很肉的电影在线观看 | a一级网站 | 午夜视频网站 | 老熟妇仑乱视频一区二区 | 久久艹综合| 色婷婷综合欧美成人 | 97久久综合区小说区图片区 | 中文字幕乱码熟妇五十中出 | 香蕉久久国产精品免 | 成在人线av无码免费高潮水 | 岛国av动作片在线观看 | 毛片免费网 | 午夜视频在线 | 成人网在线播放 | 韩国美女一级片 | 激情爱爱的免费视频 | 国产成人在线视频免费观看 | 国产百合互慰吃奶互揉视频 | 免费激情网址 | 亚洲精品久久久久国色天香 | 欧美成年网站 |