使用WinDBG調試查看C#內存轉儲文件


有時候我們想查看一個正在運行的程序內存中的數據,可以在任務管理器將內存狀態保存為轉儲文件,並使用WinDBG驗證,這里我們來試試:

0.安裝WinDBG

1.首先寫個代碼用來測試

一個class

public class MyClass
{
	public int AintValue = 123;
	public static int BintValue = 456;
	public string AstringValue = "AAA";
	public static string BstringValue = "BBB";
}

在main中引用

Console.WriteLine($"ret={d1(1)}");
MyClass MC = new MyClass();
MC.AstringValue = "SuperAAAA";
Console.ReadKey(true);//程序會停在這,這時候保存文件
Console.Write(MC.AstringValue);

2.編譯運行以后,到任務管理器保存內存轉儲文件

3.用WinDBG打開轉儲文件

點這里:

這里,然后選文件:

這里需要注意的是:
32位的WinDBG用來調試32位的程序dump文件,
64位的WInDBG用來調試64位的程序dump文件,
如果你跟我一樣用的是UWP版的WinDBG,那只能調試64位的(一定有辦法能調32位的,但我不知道,如果你知道,請回復,感謝~)

4:在內存中搜索我們要查看的對象類型


我們可以看到中間有個命令輸入框:

首先輸入兩個命令,加載兩個.net調試相關文件:

.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

notice:中間有個目錄是Framework64,如果是調試32位程序,改為Framework

加載成功.
在上面的C#代碼中,我們聲明了一個類 MyClass ,並實例化了它,現在我們要找到它,在windbg里,搜索類有兩種方式:
1:根據類名 (有可能重復)
2:根據MT(Methot Table,唯一)
剛開始是不知道MT的,所以根據類名搜索:

!dumpheap -type MyClass

notice:"!dumpheap -type"這部分不驗證大小寫,后面類名會驗證大小寫

返回的內容,第一塊是類的實例列表,第二塊是對象列表(有時候名字很像的對象也會在這里)
可以看到我們的對象只有一個,第一列是MT,如果你搜索出了多個,可以根據MT搜索:

!DumpHeap -mt 00007ff9fc0a7488

5:查看對象信息

從實例列表中可以看到這個類只有1個實例,數據格式是:
內存地址 MT 占用內存長度
我們可以從內存地址,查看這個實例的詳細信息:

!DumpObj /d 000002331f11bed0

notice:DumpObj 可以簡寫為do

可以看到下面列出了對象的所有屬性.包括靜態的,動態的.

值類型的屬性直接顯示了值
引用類型的屬性給出了引用地址

對於string類型,我們還要再進一步:

!DumpObj 000002331f112f18


就可以看到字符串值了,如果是byte[]數據,可以直接用 "dd 內存起點 內存終點" 進行查看,如果想解析成字符串可以用du命令(u表示按unicode解析)

dd 000002331f112f18+c 000002331f112f18+c+53
du 000002331f112f18+c 000002331f112f18+c+8

字符串數據前12個字節是字符串的屬性,所以要過掉


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM