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

使用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個字節是字符串的屬性,所以要過掉

發佈了55 篇原創文章 · 獲贊 72 · 訪問量 62萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章