一:背景1.講故事前段時(shí)間有位朋友在微信上找到我,說他的程序偶發(fā)性崩潰,讓我?guī)兔聪略趺椿厥拢厦娼o的壓力比較大,對(duì)于這種偶發(fā)性崩潰,比較好的辦法就是利用 AEDebug 在程序崩潰的時(shí)候自動(dòng)抽一管血出來,看看崩潰點(diǎn)是什么,其實(shí)我的系列文章中,關(guān)于崩潰類的dump比較少,剛好補(bǔ)一篇上來,話不多說,上 windbg。
二:WinDbg 分析1. 崩潰點(diǎn)在哪里在 windbg 中有一個(gè) !analyze -v 命令可以自動(dòng)化分析,輸出信息如下:
0:120> !analyze -v**********************************************************************************Exception Analysis**********************************************************************************CONTEXT:(.ecxr)rax=00000000032fed38 rbx=00000000c0000374 rcx=0000000000000000rdx=0000000000000020 rsi=0000000000000001 rdi=00007ffbada727f0rip=00007ffbada0a8f9 rsp=000000003103c8b0 rbp=0000000000c40000 r8=00007ffb779bdab7r9=00007ffb782e94c0 r10=0000000000002000r11=000000002c4aa498 r12=0000000000000000 r13=000000003103eb60r14=0000000000000000 r15=000000002c873720iopl=0nv up ei pl nz na pe nccs=0033ss=002bds=002bes=002bfs=0053gs=002befl=00000202ntdll!RtlReportFatalFailure+0x9:00007ffb`ada0a8f9 eb00jmpntdll!RtlReportFatalFailure+0xb (00007ffb`ada0a8fb)Resetting default scopeEXCEPTION_RECORD:(.exr -1)ExceptionAddress: 00007ffbada0a8f9 (ntdll!RtlReportFatalFailure+0x0000000000000009)ExceptionCode: c0000374ExceptionFlags: 00000001NumberParameters: 1Parameter[0]: 00007ffbada727f0...從卦中的 ExceptionCode: c0000374 異常碼來看,表示當(dāng)前 nt堆損壞,這就尷尬了,一個(gè)C#程序咋會(huì)把 windows nt 堆給弄壞了,可能是引入了第三方的 C++ 代碼 。
由于異常分異常前和異常后,所以需要用 .ecxr 將當(dāng)前線程切到異常前的崩潰點(diǎn),然后使用 k 觀察當(dāng)前的線程棧 。
0:120> .ecxr ; krax=00000000032fed38 rbx=00000000c0000374 rcx=0000000000000000rdx=0000000000000020 rsi=0000000000000001 rdi=00007ffbada727f0rip=00007ffbada0a8f9 rsp=000000003103c8b0 rbp=0000000000c40000 r8=00007ffb779bdab7r9=00007ffb782e94c0 r10=0000000000002000r11=000000002c4aa498 r12=0000000000000000 r13=000000003103eb60r14=0000000000000000 r15=000000002c873720iopl=0nv up ei pl nz na pe nccs=0033ss=002bds=002bes=002bfs=0053gs=002befl=00000202ntdll!RtlReportFatalFailure+0x9:00007ffb`ada0a8f9 eb00jmpntdll!RtlReportFatalFailure+0xb (00007ffb`ada0a8fb)*** Stack trace for last set context - .thread/.cxr resets it # Child-SPRetAddrCall Site00 00000000`3103c8b0 00007ffb`ada0a8c3ntdll!RtlReportFatalFailure+0x901 00000000`3103c900 00007ffb`ada1314entdll!RtlReportCriticalFailure+0x9702 00000000`3103c9f0 00007ffb`ada1345antdll!RtlpHeapHandleError+0x1203 00000000`3103ca20 00007ffb`ad9aef41ntdll!RtlpHpHeapHandleError+0x7a04 00000000`3103ca50 00007ffb`ad9be520ntdll!RtlpLogHeapFailure+0x4505 00000000`3103ca80 00007ffb`aa3882bfntdll!RtlFreeHeap+0x966e006 00000000`3103cb20 00007ffb`66fac78fKERNELBASE!LocalFree+0x2f07 00000000`3103cb60 00007ffb`66f273a4mscorlib_ni+0x63c78f08 00000000`3103cc10 00007ffb`185c4fdemscorlib_ni!System.Runtime.InteropServices.Marshal.FreeHGlobal+0x24 [f:\dd\ndp\clr\src\BCL\system\runtime\interopservices\marshal.cs @ 1212]09 00000000`3103cc50 00007ffb`185c4fa10x00007ffb`185c4fde0a 00000000`3103cca0 00007ffb`185edc820x00007ffb`185c4fa1...從卦中的 KERNELBASE!LocalFree 方法可知,程序正在釋放一個(gè) 堆塊,在釋放的過程中拋出了異常,那為什么會(huì)釋放失敗呢? 原因就比較多了,比如:
- 原因1:Free 一個(gè)已 Free 的堆塊
- 原因2:Free 了一個(gè)別人的堆塊
損壞退出 機(jī)制,用 !heap -s 命令就能顯示出這種損壞原因 。0:120> !heap -s************************************************************************************************************************NT HEAP STATS BELOW*****************************************************************************************************************************************************************************************HEAP ERROR DETECTED*****************************************************************Details:Heap address:0000000000c40000Error address: 000000002c873710Error type: HEAP_FAILURE_BLOCK_NOT_BUSYDetails:The caller performed an operation (such as a freeor a size check) that is illegal on a free block.Follow-up:Check the error's stack trace to find the culprit.Stack trace:Stack trace at 0x00007ffbada7284800007ffbad9aef41: ntdll!RtlpLogHeapFailure+0x4500007ffbad9be520: ntdll!RtlFreeHeap+0x966e000007ffbaa3882bf: KERNELBASE!LocalFree+0x2f00007ffb66fac78f: mscorlib_ni+0x63c78f00007ffb66f273a4: mscorlib_ni!System.Runtime.InteropServices.Marshal.FreeHGlobal+0x2400007ffb185c4fde: +0x185c4fdeLFH Key: 0x1d4fd2a71d8b8280Termination on corruption : ENABLEDHeapFlagsReservCommitVirtFreeListUCRVirtLockFast(k)(k)(k)(k) lengthblocks cont. heap-------------------------------------------------------------------------------------0000000000c40000 00000002167561368816364220140520LFH...
經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 一次 Redis 事務(wù)使用不當(dāng)引發(fā)的生產(chǎn)事故
- 抖音訪客記錄時(shí)間是實(shí)時(shí)更新嗎
- 抖音訪客記錄時(shí)間會(huì)錯(cuò)亂嗎
- 洗臉巾執(zhí)行標(biāo)準(zhǔn)GB和Q哪個(gè)好 一次性洗臉巾怎么挑選
- 水電費(fèi)忘記交了會(huì)影響征信嗎 通常不會(huì)受到影響!
- .NET Core C#系列之XiaoFeng.Data.IQueryableX ORM框架
- 麻疹疫苗多久打一次
- 第一次相親見面需多久
- 圓形節(jié)育環(huán)多久換一次
- wifi萬能鑰匙電腦版怎么用(聯(lián)想筆記本連wifi操作)
