国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

記一次 .NET 某工控視覺軟件 非托管泄漏分析

開發(fā) 前端
前段時(shí)間有位朋友找到我,說他的程序出現(xiàn)了非托管泄漏,某一塊的操作會(huì)導(dǎo)致非托管內(nèi)存上漲的很快,讓我?guī)兔δ嫦蚩聪率悄睦锏牟僮鳑]有釋放資源?既然找到我,那就上 WinDbg 分析吧。

一、背景

1.講故事

最近分享了好幾篇關(guān)于 非托管內(nèi)存泄漏? 的文章,有時(shí)候就是這么神奇,來求助的都是這類型的dump,一飲一啄,莫非前定。讓我被迫加深對 NT堆?, 頁堆 的理解,這一篇就給大家再帶來一篇內(nèi)存泄漏。

前段時(shí)間有位朋友找到我,說他的程序出現(xiàn)了非托管泄漏,某一塊的操作會(huì)導(dǎo)致非托管內(nèi)存上漲的很快,讓我?guī)兔δ嫦蚩聪率悄睦锏牟僮鳑]有釋放資源?既然找到我,那就上 WinDbg 分析吧。

二、WinDbg 分析

1. 哪里的內(nèi)存泄漏

看內(nèi)存泄漏還是老規(guī)矩,使用 !address -summary 命令就可以了。

0:000> !address -summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 443 7fc`685d1000 ( 7.986 TB) 99.82%
Heap 658 3`563aa000 ( 13.347 GB) 92.89% 0.16%
<unknown> 770 0`1ff5a000 ( 511.352 MB) 3.48% 0.01%
Image 1196 0`108ba000 ( 264.727 MB) 1.80% 0.00%
Stack 108 0`08c40000 ( 140.250 MB) 0.95% 0.00%
Other 31 0`081d8000 ( 129.844 MB) 0.88% 0.00%
TEB 36 0`00048000 ( 288.000 kB) 0.00% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 443 7fc`685d1000 ( 7.986 TB) 99.82%
MEM_COMMIT 2464 3`67933000 ( 13.618 GB) 94.77% 0.17%
MEM_RESERVE 336 0`300ec000 ( 768.922 MB) 5.23% 0.01%

從卦中看,當(dāng)前進(jìn)程有 13.6 G? 的提交內(nèi)存,NtHeap 占用了 13G?,很明顯這是非托管內(nèi)存泄漏,既然是非托管泄漏,那就需要二番戰(zhàn),也就是讓朋友開啟 ust?,或者啟用應(yīng)用程序驗(yàn)證器 (Application Verifier)? 開啟頁堆,目的就是記錄分配這塊內(nèi)存的源頭,這里就讓朋友用 gflags 開啟下 ust,具體怎么開,這里就不介紹了,大家可以網(wǎng)上搜一下。

2. 追蹤 ust 加持下的調(diào)用棧

有了 ust 的加持,接下來就可以繼續(xù)分析,使用 !heap -s 觀察下 nt 堆的布局。

0:000> !heap -s
SEGMENT HEAP ERROR: failed to initialize the extention
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0x0000004c4f657ebf
Termination on corruption : ENABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-------------------------------------------------------------------------------------
0000000000060000 08000002 32576 17212 32576 430 161 6 1 0 LFH
0000000000010000 08008000 64 8 64 5 1 1 0 0
0000000008810000 08001002 1088 500 1088 15 5 2 0 0 LFH
...
0000000029fb0000 08001002 88320 67408 88320 32559 343 47 189 1b7 LFH
External fragmentation 48 % (343 free blocks)
0000000029870000 08001002 512 8 512 3 1 1 0 0
...
-------------------------------------------------------------------------------------

從卦中看,commit 最大的也就是 67408k = 67M?, 這和 13G? 差的不是一星半點(diǎn),如果你了解 NtHeap 的布局,應(yīng)該知道當(dāng) 分配內(nèi)存 > 512k? 的時(shí)候,會(huì)進(jìn)入到 HEAP 的 VirtualAllocdBlocks? 雙向鏈表中,言外之意就是當(dāng)你覺得內(nèi)存對不上的時(shí)候,就要觀察下這個(gè)鏈表了,即上圖中的 Virt blocks? 列,可以看到 handle=0000000029fb0000? 的 Virt blocks=189?,接下來繼續(xù)下鉆 handle=0000000029fb0000 這個(gè)堆。

0:000> !heap -h 0000000029fb0000 
SEGMENT HEAP ERROR: failed to initialize the extention
Index Address Name Debugging options enabled
23: 29fb0000
Segment at 0000000029fb0000 to 000000002a7b0000 (007eb000 bytes committed)
Segment at 0000000026070000 to 0000000026170000 (000ff000 bytes committed)
Segment at 0000000027d10000 to 0000000027f10000 (001f7000 bytes committed)
Segment at 00000000318a0000 to 0000000031ca0000 (00400000 bytes committed)
Segment at 0000000044a00000 to 0000000045200000 (005f1000 bytes committed)
Segment at 000000004ae90000 to 000000004be60000 (00efc000 bytes committed)
Segment at 000000005b3b0000 to 000000005c380000 (00e2e000 bytes committed)
Segment at 000000005d8c0000 to 000000005e890000 (00cf1000 bytes committed)
Segment at 000000005c380000 to 000000005d350000 (002e7000 bytes committed)
Flags: 08001002
ForceFlags: 00000000
Granularity: 16 bytes
...
Virtual Alloc List: 29fb0118
Unable to read nt!_HEAP_VIRTUAL_ALLOC_ENTRY structure at 0000000043500000
Uncommitted ranges: 29fb00f8

我去,卦中出現(xiàn)了不愿看到的 Unable to read nt!_HEAP_VIRTUAL_ALLOC_ENTRY structure at 0000000043500000?,也就是說顯示不出 _HEAP_VIRTUAL_ALLOC_ENTRY 結(jié)構(gòu),可以用 dt 驗(yàn)證一下。

0:000> dt nt!_HEAP_VIRTUAL_ALLOC_ENTRY
Symbol nt!_HEAP_VIRTUAL_ALLOC_ENTRY not found.

為什么在他的機(jī)器上沒記錄到,可能和它生產(chǎn)服務(wù)器的 Windows 系統(tǒng)有關(guān),這里就不細(xì)究原因,接下來的問題是:!heap? 命令失效,該怎么把 VirtualAllocdBlocks 給挖出來呢?只能純?nèi)巳饬?..

3. 如何人肉挖 VirtualAllocdBlocks

要想人肉挖,需要一些底層知識(shí),比如下面三點(diǎn)。

  • VirtualAllocdBlocks 是什么?

VirtualAllocdBlocks 是一個(gè)記錄大塊內(nèi)存的雙向鏈表結(jié)構(gòu),可以用 dt nt!_HEAP 0000000029fb0000 命令從 HEAP 中找出來。

0:000> dt nt!_HEAP 0000000029fb0000
ntdll!_HEAP
+0x118 VirtualAllocdBlocks : _LIST_ENTRY [ 0x00000000`43500000 - 0x00000000`32970000 ]
+0x128 SegmentList : _LIST_ENTRY [ 0x00000000`29fb0018 - 0x00000000`5c380018 ]
...

0:000> dt _LIST_ENTRY 0000000029fb0000+0x118
ntdll!_LIST_ENTRY
[ 0x00000000`43500000 - 0x00000000`32970000 ]
+0x000 Flink : 0x00000000`43500000 _LIST_ENTRY [ 0x00000000`47240000 - 0x00000000`29fb0118 ]
+0x008 Blink : 0x00000000`32970000 _LIST_ENTRY [ 0x00000000`29fb0118 - 0x00000000`4ee90000 ]

從卦中可以看到, VirtualAllocdBlocks? 是一個(gè)擁有 Flink? 和 Blink 的雙向鏈表結(jié)構(gòu)。

  • _HEAP_VIRTUAL_ALLOC_ENTRY  是什么?

我們都知道 heap 的 block <512k? 是 _HEAP_ENTRY? 結(jié)構(gòu),那 block >512k? 的塊就是 _HEAP_VIRTUAL_ALLOC_ENTRY 結(jié)構(gòu),不信的話可以用 dt 導(dǎo)出來。

0:016> dt nt!_HEAP_VIRTUAL_ALLOC_ENTRY
ntdll!_HEAP_VIRTUAL_ALLOC_ENTRY
+0x000 Entry : _LIST_ENTRY
+0x010 ExtraStuff : _HEAP_ENTRY_EXTRA
+0x020 CommitSize : Uint8B
+0x028 ReserveSize : Uint8B
+0x030 BusyBlock : _HEAP_ENTRY

從卦中可以看到,除了真正的分配 BusyBlock? 之外還有一些附屬信息,比如 CommitSize? , ReserveSize? 等等,接下來就可以抽取 第一個(gè)節(jié)點(diǎn)地址 加上 +0x30? 來找到這個(gè)真正的內(nèi)存分配塊,即 0x0000000043500000 + 0x30?, 然后使用 !heap -p -a 就可以看到這個(gè)分配塊的源頭在哪里了。

0:000> !heap -p -a 0x0000000043500000 + 0x30
address 0000000043500030 found in
_HEAP @ 29fb0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0000000043500030 100100 0000 [00] 0000000043500060 1000040 - (busy VirtualAlloc)
775bc35b ntdll! ?? ::FNODOBFM::`string'+0x00000000000153eb
7fed230483b halcon!HXmalloc+0x000000000000008b
7fed22dd81d halcon!HXAllocRLTmp+0x000000000000265d
7fed22d6bd0 halcon!HXAllocTmp+0x0000000000000a80
7fed44a346a halcon!HCancelWait+0x000000000000007a
7fed2386b8f halcon!CCallHProc+0x000000000000073f
7fe83e3bcf6 +0x000007fe83e3bcf6


0:000> !ip2md 0x000007fe83e3bcf6
MethodDesc: 000007fe83c39138
Method Name: HalconDotNet.xxx
Class: 000007fe83c6b890
MethodTable: 000007fe83c3f300
mdToken: 0000000006000df5
Module: 000007fe83a7f498
IsJitted: yes
CodeAddr: 000007fe83e3bb90
Transparency: Safe critical

可以看到第一塊 size= 0x1000040 byte = 16M? 的內(nèi)存是 HalconDotNet 分配的,接下來我們多抽幾個(gè),或者用腳本來歸納一下,發(fā)現(xiàn)有大量的 88M 內(nèi)存占用,大體上歸為兩類:

  • C# 代碼分配未釋放:

圖片

  • 內(nèi)部代碼:

圖片

三、總結(jié)

最后就是把這個(gè)結(jié)果給了朋友,讓朋友看下用 !ip2md 顯示出來的托管方法,為什么沒有釋放,是不是漏了。

這個(gè)dump可以看出是因?yàn)閷?nbsp;halcon?  做了一套 DotNet 版的封裝上出現(xiàn)了一些瑕疵,這個(gè) dump 的難點(diǎn)在于當(dāng) !heap 擴(kuò)展命令失效的情況下,如何通過純手工的方式把 NTHeap 剝離的明明白白。

責(zé)任編輯:武曉燕 來源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2023-10-07 13:28:53

.NET軟件賬本

2022-09-13 17:46:19

STA模式內(nèi)存

2024-12-27 13:31:18

.NETdump調(diào)試

2024-06-06 10:51:15

自動(dòng)化系統(tǒng)推測

2023-09-26 01:11:58

MES非托管泄露

2024-07-12 11:20:34

.NET崩潰視覺程序

2024-09-14 10:28:56

.NET卡死程序

2021-11-02 07:54:41

內(nèi)存.NET 系統(tǒng)

2024-05-28 10:18:30

WPF程序數(shù)據(jù)

2023-09-27 07:23:10

.NET監(jiān)控軟件

2023-05-15 11:15:50

.NET門診語句

2024-05-31 12:56:06

.NET代碼方法

2025-09-02 01:35:00

.NET光學(xué)定位軟件

2023-06-26 00:12:46

2024-03-28 12:56:36

2023-04-06 10:52:18

2023-07-06 10:11:38

.NET模式dump

2023-03-26 20:24:50

ERP網(wǎng)站系統(tǒng)

2024-05-20 09:39:02

.NETurl線程池

2024-03-26 00:44:53

.NETCIM系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久久久免费看黄a片app| 神马电影在线观看| 99国产精品免费网站| 色综合夜色一区| 日本三日本三级少妇三级66| 亚洲免费毛片| 亚洲男人第一网站| 国产在线电影| 国产日韩精品一区二区浪潮av| 久久福利电影| 免费黄色成人| 最近2019中文字幕大全第二页| 第九色区av在线| 中文字幕在线视频一区| 日本黄色播放器| 99精品视频免费| 国产精品一区二区三区久久| 九九热这里有精品| 欧美xxxxx牲另类人与| 免费在线观看麻豆视频 | 99久久综合狠狠综合久久| 国产欧美一区二区视频| 在线日韩成人| 神马久久久久久| 国产资源在线观看入口av| 欧洲av在线精品| 中文字幕在线不卡视频| 午夜啪啪福利视频| 日韩在线a电影| 精品国产一区二区三区麻豆小说| 中文字幕伦av一区二区邻居| 久久久av电影| 亚洲精品一区三区三区在线观看| 精品久久国产老人久久综合| 暖暖日本在线观看| 欧美人妇做爰xxxⅹ性高电影| 中文字幕在线看| 亚洲午夜电影在线观看| 黄色三及免费看| 亚洲韩国精品一区| 在线免费国产| 欧美性xxxx极品hd欧美风情| 黄网站app在线观看下载视频大全官网| 国产精品久久久久9999吃药| 亚洲综合欧美激情| 亚洲人成电影网站色mp4| 免费观看黄色网| 精品福利免费观看| 成人免费在线电影| 日韩欧美国产不卡| 自拍视频在线看| 中文综合在线观看| 狂野欧美xxxx韩国少妇| 久久久久久久久久av| 精品日产乱码久久久久久仙踪林| 欧美激情中文网| 欧美国产极品| 91精品国产综合久久香蕉最新版| 91成人国产| 久久青青草综合| 国内成人精品2018免费看| 欧美日韩激情四射| 国产精品日产欧美久久久久| 两个人hd高清在线观看| 在线观看一区不卡| 成av人片在线观看www| 北条麻妃一区二区三区中文字幕 | 一区二区理论电影在线观看| 绯色av一区二区| 欧美在线视频全部完| 亚洲小说区图片| 在线播放日韩av| 天天躁日日躁狠狠躁欧美| 96pao国产成视频永久免费| 六月天综合网| 国产极品尤物在线| 亚洲综合丁香婷婷六月香| 色影院视频在线| 伊人精品在线观看| 狠狠操综合网| 日本一区二区三区免费看| 99久久国产综合精品女不卡| 超碰97在线免费| 精品国产精品一区二区夜夜嗨| av在线亚洲一区| 成人精品视频99在线观看免费| 日本美女一区二区三区| 免费看a级黄色片| 91福利国产成人精品照片| 91黄页在线观看| 欧美尤物巨大精品爽| 性8sex亚洲区入口| 丝袜老师办公室里做好紧好爽| 欧美日韩在线免费观看| 妞干网免费在线视频| 日本在线观看天堂男亚洲 | 国产精品久久天天影视| 久久精品日产第一区二区三区| 成人av片在线观看| 三上悠亚在线观看| 日韩精品在线影院| 国产日产精品_国产精品毛片| 少妇精品久久久久久久久久| 国产精品国产三级国产普通话蜜臀| yiren22亚洲综合伊人22| 这里只有精品视频| 欧美二区不卡| 成人三级视频在线播放| 5858s免费视频成人| 日韩在线网址| 久久国产精品高清| 亚洲欧美日韩在线| 国产精品专区免费| 成人xxxxx色| 国产精品久线观看视频| www在线视频| 国产成人精品午夜| 国产成人a级片| 国产福利免费在线观看| 97国产精品人人爽人人做| 久久99国产精品久久| 久久免费看视频| 97国产suv精品一区二区62| 精久久久久久久久久久| 撸视在线观看免费视频| 97久久精品国产| 国产乱码精品一区二区三区五月婷| 欧美成熟毛茸茸| 97国产在线视频| 国产成人av网站| 性欧美ⅴideo另类hd| 成人网在线免费看| 最新中文字幕一区二区三区| 国语自产精品视频在线看抢先版结局| 精品无人区一区二区三区| 亚洲柠檬福利资源导航| 精品三级久久久| 欧美 亚洲 视频| 日韩欧美另类在线| 亚洲国产日韩欧美一区二区三区| 国产精品久久久久永久免费看| xxx一区二区| 国产成人亚洲精品青草天美| 污片视频在线免费观看| 国产98在线|日韩| 亚洲成av人片在线观看| 欧美久久精品| 亚洲少妇久久久| 一本色道久久88精品综合| 免费看欧美女人艹b| 国产鲁鲁视频在线观看特色| 成人国产精品久久久久久亚洲| 亚洲女厕所小便bbb| 网友自拍一区| 国产国产人免费人成免费视频| 欧美成人一区在线| 成人精品国产福利| 日韩毛片在线| 亚洲熟妇av日韩熟妇在线| 亚洲小视频在线观看| 国产一区二区免费在线| 理论片午夜视频在线观看| 久久av秘一区二区三区| 日韩精品在线影院| 成人一区二区三区中文字幕| 中文字幕日本一区二区| 国内少妇毛片视频| 视频直播国产精品| 久久综合久色欧美综合狠狠| 国产精品亚洲综合在线观看 | 欧美日韩国产亚洲沙发| 亚洲aⅴ日韩av电影在线观看| 亚洲一级片在线观看| 日韩在线观看一区 | 天堂8在线天堂资源bt| 揄拍成人国产精品视频| 99re66热这里只有精品3直播| 国产91精品在线| 欧美国产日韩在线播放| 97精品国产97久久久久久免费 | 亚洲精品日韩精品| 国产一区二区三区日韩欧美| 91女厕偷拍女厕偷拍高清| 亚洲精品a区| 一区二区三区性视频| 久久国产精品久久| 亚洲午夜小视频| 国产精品久久久久久户外露出| 91麻豆国产自产在线观看亚洲| av色图一区| 中文字幕免费高| 777精品视频| 在线亚洲一区二区| 国产在线国偷精品免费看| 精品中文字幕一区二区三区| 天天夜夜亚洲| 亚洲美女自拍偷拍| 97久久伊人激情网| 欧美日韩在线播放三区| 国产高清不卡一区|