日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

C#托管堆遭破壞問題溯源分析

來源: 責(zé)編: 時(shí)間:2024-06-12 17:31:31 159觀看
導(dǎo)讀一、背景1. 講故事年前遇到了好幾例托管堆被損壞的案例,有些運(yùn)氣好一些,從被破壞的托管堆內(nèi)存現(xiàn)場(chǎng)能觀測(cè)出大概是什么問題,但更多的情況下是無法做出準(zhǔn)確判斷的,原因就在于生成的dump是第二現(xiàn)場(chǎng),借用之前文章的一張圖,大家

一、背景

1. 講故事

年前遇到了好幾例托管堆被損壞的案例,有些運(yùn)氣好一些,從被破壞的托管堆內(nèi)存現(xiàn)場(chǎng)能觀測(cè)出大概是什么問題,但更多的情況下是無法做出準(zhǔn)確判斷的,原因就在于生成的dump是第二現(xiàn)場(chǎng),借用之前文章的一張圖,大家可以理解一下。QeW28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片QeW28資訊網(wǎng)——每日最新資訊28at.com

為了幫助更多受此問題困擾的朋友,這篇來整理一下如何 快狠準(zhǔn) 的抓取第一現(xiàn)場(chǎng)。QeW28資訊網(wǎng)——每日最新資訊28at.com

二、抓取第一現(xiàn)場(chǎng)

1. 思路分析

要想抓到第一現(xiàn)場(chǎng),只需要讓破壞托管堆的那個(gè)線程在修改完之后,回到 CLR Pinvoke 層的時(shí)候主動(dòng)觸發(fā)GC,因?yàn)檫@時(shí)候托管堆已經(jīng)是損壞狀態(tài)了,程序也就會(huì)立即崩潰,破壞線程也就被捉j(luò)ian在床,畫個(gè)圖如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片QeW28資訊網(wǎng)——每日最新資訊28at.com

那如何讓 CLR:PInvoke 主動(dòng)觸發(fā)GC呢?這就需要借助微軟的 MDA 托管調(diào)試助手,它有一個(gè) gcUnmanagedToManaged 配置項(xiàng)就是專門做這件事情的,參考網(wǎng)址:https://learn.microsoft.com/zh-cn/dotnet/framework/debug-trace-profile/gcunmanagedtomanaged-mdaQeW28資訊網(wǎng)——每日最新資訊28at.com

2. 如何配置 MDA

MDA 的配置非常簡(jiǎn)單,大體上分兩步:QeW28資訊網(wǎng)——每日最新資訊28at.com

  1. 提交注冊(cè)表開啟MDA

這里使用注冊(cè)表的方式,需要注意的是,程序和操作系統(tǒng)位數(shù)一致的話采用如下方式。QeW28資訊網(wǎng)——每日最新資訊28at.com

Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework]"MDA"="1"

如果不一致,采用如下配置,比如 32bit 程序跑在 64bit 系統(tǒng)上。QeW28資訊網(wǎng)——每日最新資訊28at.com

Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/.NETFramework]"MDA"="1"

這里我用的是第二段內(nèi)容,按照官方文檔描述,將內(nèi)容保存到 MDAEnable.reg 中,然后在 注冊(cè)表編輯器 上導(dǎo)入即可。QeW28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片QeW28資訊網(wǎng)——每日最新資訊28at.com

開啟應(yīng)用程序級(jí)捕獲

為了能夠讓 gcUnmanagedToManaged 生效,需要新建應(yīng)用程序打頭的配置文件,比如:Example_16_1_2.exe.mda.config,內(nèi)容如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

<mdaConfig> <assistants>  <gcUnmanagedToManaged/> </assistants></mdaConfig>

完整截圖:QeW28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片QeW28資訊網(wǎng)——每日最新資訊28at.com

這樣就算配置好了,當(dāng)程序在 PInvoke 時(shí),CLR 會(huì)讀取注冊(cè)表的 MDA 值,如果開啟的話就會(huì)讀取 config 中 gcUnmanagedToManaged 子節(jié)做相應(yīng)的邏輯。QeW28資訊網(wǎng)——每日最新資訊28at.com

tips:如果配置不生效,保守一點(diǎn)的話,建議重啟下機(jī)器。QeW28資訊網(wǎng)——每日最新資訊28at.com

3. 一個(gè)托管堆破壞的測(cè)試案例

為了演示托管堆損壞,我準(zhǔn)備將一個(gè) string 傳給 C++,然后讓 C++ 溢出它來實(shí)現(xiàn)托管堆破壞。QeW28資訊網(wǎng)——每日最新資訊28at.com

C# 代碼如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

namespace Example_16_1_2{    internal class Program    {        [DllImport("Example_16_1_3.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]        public extern static void Alloc(string str);        static void Main(string[] args)        {            Test();            Task.Factory.StartNew(() =>            {                Thread.Sleep(3000);                GC.Collect();            });            Console.ReadLine();        }        static void Test()        {            var str = "hello";            var str2 = "world!";            Alloc(str);        }    }}

C++ 代碼如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

extern "C"{ _declspec(dllexport) void Alloc(wchar_t* c);}#include "iostream"#include <Windows.h>using namespace std;void Alloc(wchar_t* c){ for (size_t i = 0; i < 10; i++) {  *c++ = 'a'; } wprintf(L"%s /n", c);}

從代碼邏輯看,只要 Alloc(str) 的線程棧上觸發(fā)了 GC 就是第一現(xiàn)場(chǎng),Task 下的 GC.Collect(); 是第二現(xiàn)場(chǎng),如果是前者目的就達(dá)到了。QeW28資訊網(wǎng)——每日最新資訊28at.com

激動(dòng)人心的時(shí)刻到了,把程序跑起來后,由于程序崩潰,procdump 立即給我抓了一個(gè) crash dump,截圖如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片QeW28資訊網(wǎng)——每日最新資訊28at.com

接下來打開 windbg,從序幕信息看果然是 GC 清掃的時(shí)候出的問題,托管堆也是損壞狀態(tài),信息如下:QeW28資訊網(wǎng)——每日最新資訊28at.com

Debug session time: Sun Jan 29 10:14:21.000 2023 (UTC + 8:00)System Uptime: 0 days 1:14:11.423Process Uptime: not available.................................Loading unloaded module list..This dump file has an exception of interest stored in it.The stored exception information can be accessed via .ecxr.(4460.52ac): Access violation - code c0000005 (first/second chance not available)For analysis of this file, run !analyze -veax=00610060 ebx=00000000 ecx=02da23a4 edx=00000001 esi=02da2370 edi=02da2388eip=79a6f2d1 esp=00d3ef64 ebp=00d3f104 iopl=0         nv up ei pl nz na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206clr!WKS::gc_heap::plan_phase+0x79b:79a6f2d1 f70000000080    test    dword ptr [eax],80000000h ds:002b:00610060=????????0:000> !VerifyHeapCould not request method table data for object 02DA1228 (MethodTable: 0000000C).Last good object: 02DA121C.object 03da1020: bad member 02DA1228 at 03DA1098Last good object: 03DA1010.object 03da2338: bad member 02DA1228 at 03DA2340Last good object: 03DA2328.object 03da3568: bad member 02DA2364 at 03DA357CLast good object: 03DA3558.Failed to request SyncBlk at index 1.

那是不是主線程引發(fā)的GC呢?切過去便知。QeW28資訊網(wǎng)——每日最新資訊28at.com

0:000> ~0seax=00610060 ebx=00000000 ecx=02da23a4 edx=00000001 esi=02da2370 edi=02da2388eip=79a6f2d1 esp=00d3ef64 ebp=00d3f104 iopl=0         nv up ei pl nz na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206clr!WKS::gc_heap::plan_phase+0x79b:79a6f2d1 f70000000080    test    dword ptr [eax],80000000h ds:002b:00610060=????????0:000> !clrstackOS Thread Id: 0x52ac (0)Child SP       IP Call Site00d3f220 79a6f2d1 [HelperMethodFrame: 00d3f220] System.StubHelpers.StubHelpers.TriggerGCForMDA()00d3f294 02bc0aa7 DomainBoundILStubClass.IL_STUB_PInvoke(System.String)00d3f298 02bc09c9 [InlinedCallFrame: 00d3f298] Example_16_1_2.Program.Alloc(System.String)00d3f2e0 02bc09c9 Example_16_1_2.Program.Test() [D:/testdump/Example/Example_16_1_2/Program.cs @ 35]00d3f2f0 02bc0900 Example_16_1_2.Program.Main(System.String[]) [D:/testdump/Example/Example_16_1_2/Program.cs @ 19]00d3f490 7996f036 [GCFrame: 00d3f490] 0:000> k 10 # ChildEBP RetAddr      00 00d3f104 79a68153     clr!WKS::gc_heap::plan_phase+0x79b01 00d3f124 79a6847b     clr!WKS::gc_heap::gc1+0xbc02 00d3f13c 79a68585     clr!WKS::gc_heap::garbage_collect+0x36703 00d3f15c 79b1ddbd     clr!WKS::GCHeap::GarbageCollectGeneration+0x1bd04 00d3f16c 79b1de34     clr!WKS::GCHeap::GarbageCollectTry+0x7105 00d3f198 79d20aed     clr!WKS::GCHeap::GarbageCollect+0xac06 00d3f204 79d066c0     clr!TriggerGCForMDAInternal+0x7d07 00d3f28c 02bc0aa7     clr!StubHelpers::TriggerGCForMDA+0x61WARNING: Frame IP not in any known module. Following frames may be wrong.08 00d3f2d8 02bc09c9     0x2bc0aa709 00d3f2e8 02bc0900     Example_16_1_2!Example_16_1_2.Program.Test+0x39 [D:/testdump/Example/Example_16_1_2/Program.cs @ 35] 0a 00d3f318 7996f036     Example_16_1_2!Example_16_1_2.Program.Main+0x30 [D:/testdump/Example/Example_16_1_2/Program.cs @ 19] 0b 00d3f324 799722da     clr!CallDescrWorkerInternal+0x340c 00d3f378 7997859b     clr!CallDescrWorkerWithHandler+0x6b0d 00d3f3ec 79b1b11b     clr!MethodDescCallSite::CallTargetWorker+0x16a0e 00d3f510 79b1b7fa     clr!RunMain+0x1b30f 00d3f77c 79b1b727     clr!Assembly::ExecuteMainMethod+0xf7

從線程棧上的 clr!StubHelpers::TriggerGCForMDA 來看,在 Pinvoke 層果然主動(dòng)觸發(fā)了 GC,成功將 Program.Alloc 這個(gè)非托管方法捉j(luò)ian在床。QeW28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-93367-0.htmlC#托管堆遭破壞問題溯源分析

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: PHP二進(jìn)制 Swoole-Cli 了解一下

下一篇: Go 面試中的隱藏陷阱:SliceHeader 問題解析

標(biāo)簽:
  • 熱門焦點(diǎn)
  • iPhone賣不動(dòng)了!蘋果股價(jià)創(chuàng)年內(nèi)最大日跌幅:市值一夜蒸發(fā)萬億元

    8月5日消息,今天凌晨美股三大指數(shù)高開低走集體收跌,道指跌0.41%;納指跌0.36%;標(biāo)普500指數(shù)跌0.52%。熱門科技股也都變化極大,其中蘋果報(bào)181.99美元,跌4.8%,創(chuàng)
  • 一年經(jīng)驗(yàn)在二線城市面試后端的經(jīng)驗(yàn)分享

    忠告這篇文章只適合2年內(nèi)工作經(jīng)驗(yàn)、甚至沒有工作經(jīng)驗(yàn)的朋友閱讀。如果你是2年以上工作經(jīng)驗(yàn),請(qǐng)果斷劃走,對(duì)你沒啥幫助~主人公這篇文章內(nèi)容來自 「升職加薪」星球星友 的投稿,坐
  • 如何通過Python線程池實(shí)現(xiàn)異步編程?

    線程池的概念和基本原理線程池是一種并發(fā)處理機(jī)制,它可以在程序啟動(dòng)時(shí)創(chuàng)建一組線程,并將它們置于等待任務(wù)的狀態(tài)。當(dāng)任務(wù)到達(dá)時(shí),線程池中的某個(gè)線程會(huì)被喚醒并執(zhí)行任務(wù),執(zhí)行完任
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對(duì)帶有指定屬性的 HTML 元素設(shè)置樣式。可以為擁有指定屬性的 HTML 元素設(shè)置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡(jiǎn)單而
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動(dòng)設(shè)備上有一個(gè)固定元素,當(dāng)激活虛擬鍵盤時(shí),該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認(rèn)行為,在本文中,我們將探討這個(gè)問題、為什么會(huì)發(fā)生
  • 品牌洞察丨服務(wù)本地,美團(tuán)直播成效幾何?

    來源:17PR7月11日,美團(tuán)App首頁(yè)推薦位出現(xiàn)&ldquo;美團(tuán)直播&rdquo;的固定入口。在直播聚合頁(yè)面,外賣&ldquo;神槍手&rdquo;直播間、美團(tuán)旅行直播間、美團(tuán)買菜直播間等均已上線,同時(shí)
  • 東方甄選單飛:有些鳥注定是關(guān)不住的

    作者:彭寬鴻來源:華爾街科技眼&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;東方甄選創(chuàng)始人俞敏洪帶隊(duì)的&ldquo;7天甘肅行&rdquo;直播活動(dòng)已在近日順利收官。成立后一
  • 首發(fā)天璣9200+ iQOO Neo8系列發(fā)布首銷售價(jià)2299元起

    2023年5月23日晚,iQOO Neo8系列正式發(fā)布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro強(qiáng)悍登場(chǎng),限時(shí)售價(jià)3099元起;價(jià)位段最強(qiáng)性能手機(jī)iQOO Neo8同期上市
  • SN570 NVMe SSD固態(tài)硬盤 價(jià)格與性能兼具

    SN570 NVMe SSD固態(tài)硬盤是西部數(shù)據(jù)發(fā)布的最新一代WD Blue系列的固態(tài)硬盤,不僅閃存技術(shù)更為精進(jìn),性能也得到了進(jìn)一步的躍升。WD Blue SN570 NVMe SSD的包裝外
Top 主站蜘蛛池模板: 黄山市| 井冈山市| 永善县| 安国市| 玉屏| 霍林郭勒市| 缙云县| 阳山县| 和田县| 永靖县| 马关县| 丰城市| 冀州市| 竹溪县| 四子王旗| 商都县| 全州县| 黎平县| 安阳县| 醴陵市| 阳城县| 湄潭县| 云浮市| 华阴市| 万盛区| 察雅县| 静宁县| 馆陶县| 顺义区| 永嘉县| 灵宝市| 新津县| 宁乡县| 沐川县| 温州市| 重庆市| 思茅市| 宜黄县| 乌兰察布市| 交口县| 陇川县|