国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

這篇具有很好參考價值的文章主要介紹了Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

一、簡介
    
今天是《Net 高級調(diào)試》的第四篇文章。到今天為止,也有三篇文章了,對 Windbg 也有初步的認(rèn)識了,當(dāng)然,一個工具流暢、熟練的使用,對于我們調(diào)試 Net 程序是至關(guān)重要的。在前幾篇文章的基礎(chǔ)上,我們這篇文章主要介紹一些和使用 Windbg 有關(guān)的命令和操作。就我個人而言,第一次接觸這個東西,還是挺難的,以前從來沒有用過 Windbg,用的最多的就是 Visual Studio 的調(diào)試功能。不怕大家笑話,如何通過 Windbg 加載一個 exe,我都不知道,更不要談加載 DUMP 文件。我看第一遍視頻的時候,也不知道說了個啥,命令的執(zhí)行,調(diào)試的開始,都感覺是一頭霧水,似懂非懂,自己一實(shí)操,總是得不到別人調(diào)試那樣的結(jié)果,很是郁悶。怎么辦呢?沒辦法,要想學(xué)會,除了努力那就是堅(jiān)持。針對視頻,放慢速度,一幀一幀的按著視頻的操作,自己來一遍,速度雖然慢,但是有些操作開始有了感覺了,當(dāng)整個視頻系列看了一遍,所有操作都操作一遍,終于有些頭緒了。還是那句老話,一遍不行,那就再來一遍,還不行,那就再來一遍,俗話說的好,書讀千遍,其意自現(xiàn),我這是第三遍。
     如果在沒有說明的情況下,所有代碼的測試環(huán)境都是 Net Framewok 4.8,但是,有時候?yàn)榱瞬榭丛创a,可能需要使用 Net Core 的項(xiàng)目,我會在項(xiàng)目章節(jié)里進(jìn)行說明。好了,廢話不多說,開始我們今天的調(diào)試工作。
    調(diào)試環(huán)境我需要進(jìn)行說明,以防大家不清楚,具體情況我已經(jīng)羅列出來。
          操作系統(tǒng):Windows Professional 10
          調(diào)試工具:Windbg Preview(可以去Microsoft Store 去下載)
          開發(fā)工具:Visual Studio 2022
          Net 版本:Net Framework 4.8
          CoreCLR源碼:源碼下載
二、相關(guān)知識
    
1、Windbg 動態(tài)調(diào)試
          1.1、調(diào)試概況
              在任何一種調(diào)試中都有兩個組件:調(diào)試器本身,調(diào)試目標(biāo)。
              當(dāng)調(diào)試器【W(wǎng)indbg】附加進(jìn)程【Attach to Process】時,調(diào)試器會給 目標(biāo)程序 注入一個遠(yuǎn)程線程并用 int 3 中斷程序,后續(xù)和 Net 程序中的?DebuggerRCThread 線程交互執(zhí)行命令。int 3 指令之所以可以讓進(jìn)程中斷,主要是來自于 CPU 硬件中斷,當(dāng)調(diào)試器發(fā)出了一個 int 3 的中斷請求,CPU會到內(nèi)核態(tài)執(zhí)行3號例程,也就是執(zhí)行【中斷向量表】,內(nèi)核執(zhí)行中斷的操作。
              Actor------------》調(diào)試器(Windbg)《------------》調(diào)試目標(biāo)(Net 程序,C++程序...)
              以上圖例就是一個調(diào)試器的作用和所處的地位。

     2、程序的中斷和恢復(fù)執(zhí)行
          2.1、中斷執(zhí)行(讓程序中斷有4中方式)
              a、使用WinDbg 啟動程序,在進(jìn)程初始化函數(shù)中,如果發(fā)現(xiàn)有調(diào)試器附加在上面,就會執(zhí)行 break 中斷?!?br>                  說明一下:Windbg 調(diào)試器剛開始的中斷就是 int 3 中斷,但是這個中斷的時機(jī)很早,我們可以做一些初始化的工作,比如:加載SOS.dll 等類似的工作。                
              b、附加進(jìn)程,調(diào)試器會注入遠(yuǎn)程線程執(zhí)行 int 3 中斷程序。
                  這個挺簡單的,我們雙擊程序,直接運(yùn)行。然后通過 Windbg 的【Attach to process】附加進(jìn)程,就可以進(jìn)入調(diào)試器界面,這個時候,其實(shí)什么也不用做,調(diào)試器已經(jīng)暫停了,這個暫停就是 int 3 中斷。我們通過 Windbg 的【break】命令也是 int 3 中斷。當(dāng)然,我們通過 C# Debugger.Break() 代碼執(zhí)行的也是 int 3 的中斷。
              c、使用 bp 命令給程序下斷點(diǎn)。
                  我們可以通過【u】命令查看方法的匯編代碼,找到想要設(shè)斷點(diǎn)的代碼的地址,直接通過這個地址來下斷點(diǎn),當(dāng)程序再次運(yùn)行的時候,就會在這個斷點(diǎn)處暫停?!                ?br>              d、異常中斷。
                 ? 異常中斷的流程是:當(dāng)你的程序發(fā)生異常,會從用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài),內(nèi)核態(tài)檢測到你的程序附加了調(diào)試器,內(nèi)核態(tài)就會把這個請求轉(zhuǎn)交給調(diào)試器,調(diào)試器也就能中斷了,可以調(diào)試了。
          2.2、恢復(fù)執(zhí)行
              可以使用 g 命令回復(fù)程序的執(zhí)行。

     3、單步調(diào)試代碼。
          當(dāng)我們調(diào)試程序的時候,最多的時候是使用 Visual Studio 的 f10、f11、f5這樣的命令,在 Windbg 中也有類似的命令可以使用。
        
  3.1、p 命令
              p(step):命令其實(shí)就是VS 中的 f10 快捷鍵,單步執(zhí)行,遇到函數(shù)也是當(dāng)成一條指令執(zhí)行,不會進(jìn)入函數(shù)體。
              
          3.2、t 命令
              
t(trace):命令其實(shí)就是 VS 的 f11 快捷鍵,它是一種進(jìn)入函數(shù)的單步執(zhí)行調(diào)試。
              
          3.3、pc 命令
              pc(Step to Next Call)?? ?就是一直運(yùn)行直到遇到 call 為止,不會進(jìn)入函數(shù)體,call 是一個函數(shù)調(diào)用,匯編指令。
              
          3.4、tc 命令
           
tc(Trace to Next Call)?? ?和 pc 不同的是,tc 會進(jìn)入方法體,直到遇到 call 為止。

          3.5、pt 命令
              pt(Step to Next Return)?? ?遇到下一個 ret 為止。???
              
          3.6、tt 命令
              tt(Trace to Next Return)?? ?會進(jìn)入函數(shù)體直到遇到 ret 為止。遞歸的意思。
              
    4、退出測試會話
          結(jié)束調(diào)試會話,有兩個目的,看是否保留程序的執(zhí)行。
          4.1、q(quit):結(jié)束調(diào)試會話+調(diào)試程序退出
              調(diào)試會話結(jié)束,應(yīng)用程序也會退出。
          4.2、qd(quit and detach):結(jié)束調(diào)試會話+調(diào)試程序繼續(xù)運(yùn)行
              調(diào)試會話結(jié)束,應(yīng)用程序保持運(yùn)行態(tài),不會退出。

三、調(diào)試過程
    
廢話不多說,這一節(jié)是具體的調(diào)試操作的過程,又可以說是眼見為實(shí)的過程,在開始之前,我還是要啰嗦兩句,這一節(jié)分為兩個部分,第一部分是測試的源碼部分,沒有代碼,當(dāng)然就談不上測試了,調(diào)試必須有載體。第二部分就是根據(jù)具體的代碼來證實(shí)我們學(xué)到的知識,是具體的眼見為實(shí)。
    1、測試源碼
        
1.1、Example_4_1_1
Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試
 1 namespace Example_4_1_1
 2 {
 3     internal class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             for (int i = 0; i < int.MaxValue; i++)
 8             {
 9                 Console.WriteLine($"i={i}");
10                 Thread.Sleep(1000);
11             }
12             Console.ReadLine();
13         }
14     }
15 }
View Code
        1.2、Example_4_1_2
Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試
 1 namespace Example_4_1_2
 2 {
 3     internal class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Debugger.Break();
 8 
 9             int a = 10;
10             int b = 12;
11 
12             var sum = a + b;
13 
14             Console.WriteLine($"sum={sum}");
15 
16             Console.ReadLine();
17         }
18     }
19 }
View Code
        1.3、Example_4_1_3
Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試
 1 namespace Example_4_1_3
 2 {
 3     internal class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Run();
 8 
 9             Console.ReadLine();
10         }
11 
12         static void Run()
13         {
14             Console.WriteLine("請輸入一個除數(shù):");
15             var num = Console.ReadLine();
16             var result = 10 / Convert.ToInt32(num);
17         }
18     }
19 }
View Code
        1.4、Example_4_1_4
Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試
 1 namespace Example_4_1_4
 2 {
 3     internal class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Sum1(10);
 8             Debugger.Break();
 9 
10             int i = 10;
11             int j = 20;
12 
13             var sum = Sum1(i);
14             Console.WriteLine($"sum={sum}");
15 
16             Console.ReadLine();
17         }
18 
19         private static int Sum1(int a)
20         {
21             var i = a;
22             var j = 11;
23             int sum = Sum2(i, j);
24 
25             return sum;
26         }
27 
28         private static int Sum2(int a, int b)
29         {
30             var i = a;
31             var j = b;
32             var k = 13;
33 
34             var sum = Sum3(i, j, k);
35             return sum;
36         }
37 
38         private static int Sum3(int i, int j, int k)
39         {
40             return i + j + k;
41         }
42     }
43 }
View Code

    2、眼見為實(shí)
          2.1、Windbg【Attach to Process】附加進(jìn)程,通過 int 3 命令中斷程序。
              測試代碼:Example_4_1_1
            程序很簡單,直接運(yùn)行 exe 程序,打開 Windbg,點(diǎn)擊菜單【attach to process】進(jìn)入調(diào)試器界面。其實(shí)什么操作都不用做,我們就可以看到調(diào)試器的輸出結(jié)果。特別強(qiáng)調(diào),紅色標(biāo)注的就是 int 3中斷。
1 ModLoad: 6fa30000 6faba000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
2 ModLoad: 75f50000 75feb000   C:\Windows\System32\OLEAUT32.dll
3 (5384.3250): Break instruction exception - code 80000003 (first chance)
4 eax=00270000 ebx=00000000 ecx=7790cee0 edx=7790cee0 esi=7790cee0 edi=7790cee0
5 eip=778d3410 esp=04c2f92c ebp=04c2f958 iopl=0         nv up ei pl zr na pe nc
6 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
7 ntdll!DbgBreakPoint:
8 778d3410 cc              int     3

              當(dāng)然,我們也可以通過【g】命令,繼續(xù)運(yùn)行程序,然后點(diǎn)擊工具欄的【break】按鈕,程序就進(jìn)入中斷,這里的結(jié)果和上面是一樣的。

1 0:006> g
2 (5384.528c): Break instruction exception - code 80000003 (first chance)
3 eax=00279000 ebx=00000000 ecx=7790cee0 edx=7790cee0 esi=7790cee0 edi=7790cee0
4 eip=778d3410 esp=04eaf960 ebp=04eaf98c iopl=0         nv up ei pl zr na pe nc
5 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
6 ntdll!DbgBreakPoint:
7 778d3410 cc              int     3

              當(dāng)然,也可以通過【u】命令,查看?ntdll!DbgBreakPoint的匯編代碼?!         ?/p>

1 0:008> u ntdll!DbgBreakPoint
2 ntdll!DbgBreakPoint:
3 778d3410 cc              int     3
4 778d3411 c3              ret(方法返回)

              我們也可以查看【Disassembly】視圖,截圖如下:
              Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試


            解釋內(nèi)核態(tài):涉及到內(nèi)核態(tài)的執(zhí)行,我們也可以通過Windbg 查看,重新在打開一個 Windbg,點(diǎn)擊【文件】----》【Attach kernel】,選擇【local】項(xiàng),點(diǎn)擊【ok】按鈕,進(jìn)入調(diào)試器界面。然后,我們可以輸入【!idt】命令來查看。
 1 lkd> !idt
 2 
 3 Dumping IDT: fffff80069a91000
 4 
 5 00:    fffff80064b93100 nt!KiDivideErrorFaultShadow
 6 01:    fffff80064b93180 nt!KiDebugTrapOrFaultShadow    Stack = 0xFFFFF80069A959D0
 7 02:    fffff80064b93240 nt!KiNmiInterruptShadow    Stack = 0xFFFFF80069A957D0
 8 03:    fffff80064b932c0 nt!KiBreakpointTrapShadow
 9 04:    fffff80064b93340 nt!KiOverflowTrapShadow
10 ..................

              紅色標(biāo)注的就是在內(nèi)核態(tài)的中斷函數(shù),我們可以使用【u】命令,查看他的匯編代碼。

 1 lkd> u nt!KiBreakpointTrapShadow
 2 nt!KiBreakpointTrapShadow:
 3 fffff800`64b932c0 f644240801      test    byte ptr [rsp+8],1
 4 fffff800`64b932c5 7467            je      nt!KiBreakpointTrapShadow+0x6e (fffff800`64b9332e)
 5 fffff800`64b932c7 0f01f8          swapgs
 6 fffff800`64b932ca 0faee8          lfence
 7 fffff800`64b932cd 650fba24251890000001 bt  dword ptr gs:[9018h],1
 8 fffff800`64b932d7 720c            jb      nt!KiBreakpointTrapShadow+0x25 (fffff800`64b932e5)
 9 fffff800`64b932d9 65488b242500900000 mov   rsp,qword ptr gs:[9000h]
10 fffff800`64b932e2 0f22dc          mov     cr3,rsp
            解釋:,我們可以通過【~* k】命令,打印出所有線程棧,......表示省略,內(nèi)容太多,沒必要,顯示重要的就可以了。
              
 1 0:008> ~*k
 2 
 3    0  Id: 5384.4128 Suspend: 1 Teb: 0025e000 Unfrozen
 4  # ChildEBP RetAddr      
 5 00 0057ee00 75942d3b     ntdll!NtDelayExecution+0xc
 6 ......
 7 
 8    1  Id: 5384.22a4 Suspend: 1 Teb: 00261000 Unfrozen
 9  # ChildEBP RetAddr      
10 00 0088fab8 778b0f30     ntdll!NtWaitForWorkViaWorkerFactory+0xc
11 ......
12 
13    2  Id: 5384.3034 Suspend: 1 Teb: 00264000 Unfrozen
14  # ChildEBP RetAddr      
15 00 00affb9c 778b0f30     ntdll!NtWaitForWorkViaWorkerFactory+0xc
16 .......
17 
18    3  Id: 5384.35fc Suspend: 1 Teb: 00267000 Unfrozen
19  # ChildEBP RetAddr      
20 00 00bff9f0 778b0f30     ntdll!NtWaitForWorkViaWorkerFactory+0xc
21 ......
22 
23    4  Id: 5384.3c50 Suspend: 1 Teb: 0026a000 Unfrozen
24  # ChildEBP RetAddr      
25 00 0258f804 75939623     ntdll!NtWaitForMultipleObjects+0xc
26 01 0258f804 711567d7     KERNELBASE!WaitForMultipleObjectsEx+0x103
27 02 0258f86c 711566ff     clr!DebuggerRCThread::MainLoop+0x99
28 03 0258f898 71156620     clr!DebuggerRCThread::ThreadProc+0xd0
29 04 0258f8c4 7711f989     clr!DebuggerRCThread::ThreadProcStatic+0xa3
30 05 0258f8d4 778c7084     KERNEL32!BaseThreadInitThunk+0x19
31 06 0258f930 778c7054     ntdll!__RtlUserThreadStart+0x2f
32 07 0258f940 00000000     ntdll!_RtlUserThreadStart+0x1b
33 
34    5  Id: 5384.2050 Suspend: 1 Teb: 0026d000 Unfrozen
35  # ChildEBP RetAddr      
36 00 0475fabc 75939623     ntdll!NtWaitForMultipleObjects+0xc
37 ......
38 
39    6  Id: 5384.2ce0 Suspend: 1 Teb: 00276000 Unfrozen
40  # ChildEBP RetAddr      
41 00 04c2f84c 778b0f30     ntdll!NtWaitForWorkViaWorkerFactory+0xc
42 ......
43 
44    7  Id: 5384.489c Suspend: 1 Teb: 00273000 Unfrozen
45  # ChildEBP RetAddr      
46 ......
47 04 04d6ffb0 00000000     ntdll!_RtlUserThreadStart+0x1b
48 
49 #  8  Id: 5384.528c Suspend: 1 Teb: 00279000 Unfrozen
50  # ChildEBP RetAddr      
51 00 04eaf98c 7790cf19     ntdll!DbgBreakPoint(int 3 中斷)
52 01 04eaf98c 7711f989     ntdll!DbgUiRemoteBreakin+0x39
53 02 04eaf99c 778c7084     KERNEL32!BaseThreadInitThunk+0x19
54 03 04eaf9f8 778c7054     ntdll!__RtlUserThreadStart+0x2f
55 04 04eafa08 00000000     ntdll!_RtlUserThreadStart+0x1b


          2.2、使用WinDbg 啟動程序,在進(jìn)程初始化函數(shù)中斷進(jìn)程。
              測試代碼:Example_4_1_2
            
我們編譯項(xiàng)目,打開 Windbg,點(diǎn)擊【文件】----》【launch executable】附加程序,打開調(diào)試器的界面,程序已經(jīng)處于中斷狀態(tài)。我們可以看到,如下輸出:
 1 Executable search path is: 
 2 ModLoad: 00be0000 00be8000   Example_4_1_2.exe
 3 ModLoad: 77860000 77a02000   ntdll.dll
 4 ModLoad: 717e0000 71832000   C:\Windows\SysWOW64\MSCOREE.DLL
 5 ModLoad: 77100000 771f0000   C:\Windows\SysWOW64\KERNEL32.dll
 6 ModLoad: 75820000 75a33000   C:\Windows\SysWOW64\KERNELBASE.dll
 7 ModLoad: 5efe0000 5f07f000   C:\Windows\SysWOW64\apphelp.dll
 8 (300c.20b8): Break instruction exception - code 80000003 (first chance)
 9 eax=00000000 ebx=00000000 ecx=534d0000 edx=00000000 esi=77871f64 edi=7787252c
10 eip=77910de2 esp=00f7f824 ebp=00f7f850 iopl=0         nv up ei pl zr na pe nc
11 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
12 ntdll!LdrpDoDebuggerBreak+0x2b:
13 77910de2 cc              int     3

              紅色部分需要注意,然后我們使用【u】命令查看它的匯編代碼。

 1 0:000> u ntdll!LdrpDoDebuggerBreak+0x2b
 2 ntdll!LdrpDoDebuggerBreak+0x2b:
 3 77910de2 cc              int     3
 4 77910de3 eb07            jmp     ntdll!LdrpDoDebuggerBreak+0x35 (77910dec)
 5 77910de5 33c0            xor     eax,eax
 6 77910de7 40              inc     eax
 7 77910de8 c3              ret
 8 77910de9 8b65e8          mov     esp,dword ptr [ebp-18h]
 9 77910dec c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh
10 77910df3 8b4df0          mov     ecx,dword ptr [ebp-10h]

              我們可以使用【k】命令,繼續(xù)查看。

1 0:000> k
2  # ChildEBP RetAddr      
3 00 00f7f850 7790b2f8     ntdll!LdrpDoDebuggerBreak+0x2b(int 3 中斷)
4 01 00f7fab0 778ba3d1     ntdll!LdrpInitializeProcess+0x1c98(進(jìn)程初始化的時候執(zhí)行的 break中斷,)
5 02 00f7fb08 778ba2c1     ntdll!_LdrpInitialize+0xba
6 03 00f7fb14 00000000     ntdll!LdrInitializeThunk+0x11

               ntdll是一個網(wǎng)關(guān)函數(shù)dll,如果想使用內(nèi)核的功能幾必須通過 ntdll 里面的函數(shù)。ntdll!LdrpDoDebuggerBreak 這個中斷是在進(jìn)程初始化之前進(jìn)行的,是很早的一個時機(jī),加載的東西也不多,只有【Example_4_1_2.exentdll.dll,MSCOREE.DLL,KERNEL32.dll...】,之所以這樣,可以讓我們設(shè)置一些或者說配置一些初始化的東西,比如:加載 SOS等。

            
        
2.3、使用 bp 命令給程序下斷點(diǎn),可以讓程序中斷。
            
測試代碼:Example_4_1_2
            比如,我們在【int a = 10;】這樣代碼下斷點(diǎn),行數(shù):12.
            Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

               我們編譯項(xiàng)目,打開 Windbg,點(diǎn)擊【文件】----》【launch executable】附加程序,打開調(diào)試器的界面,程序已經(jīng)處于中斷狀態(tài)。我們使用【g】命令,繼續(xù)運(yùn)行,然后我們使用【!clrstack】命令,查看線程棧。

1 0:000> !clrstack
2 OS Thread Id: 0x3c54 (0)
3 Child SP       IP Call Site
4 00d5ed38 7597f262 [HelperMethodFrame: 00d5ed38] System.Diagnostics.Debugger.BreakInternal()
5 00d5edb4 7064f195 System.Diagnostics.Debugger.Break() [f:\dd\ndp\clr\src\BCL\system\diagnostics\debugger.cs @ 91]
6 00d5eddc 02ba0886 Example_4_1_2.Program.Main(System.String[]) [E:\Visual Studio 2022\...\Example_4_1_2\Program.cs @ 10]
7 00d5ef78 70faf036 [GCFrame: 00d5ef78] 

                紅色標(biāo)注的是 Main 方法的地址,然后執(zhí)行【!u 02ba0886】命令,查看他的匯編代碼。

1 0:000> !u 02ba0886
2 Normal JIT generated code
3 Example_4_1_2.Program.Main(System.String[])
4 Begin 02ba0848, size a3
5 
6 ......
7 
8 E:\Visual Studio 2022\...\Example_4_1_2\Program.cs @ 12:(這個行號就是C# 代碼的行號)
9 02ba0887 c745f00a000000  mov     dword ptr [ebp-10h],0Ah

                我們找到了代碼的位置,就可以下斷點(diǎn)了,使用【bp】命令。

0:000> bp 02ba0887

                【g】繼續(xù)運(yùn)行,就會到斷點(diǎn)出暫停。

              Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

                效果如圖。


        
2.4、觸發(fā)異常,也可以讓程序中斷。
            
測試代碼:Example_4_1_3
              代碼很簡單,我簡單說一些流程,我們首先將要測試的項(xiàng)目編譯好,然后打開 Windbg,通過【launch executable】附加應(yīng)用程序,調(diào)試器會響應(yīng)一個 int 3中斷,我們通過【g】命令,繼續(xù)運(yùn)行程序。程序提示輸入一個數(shù)字,我輸入0,肯定就會異常了。
           效果如圖:
           Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

              異常中斷的代碼是:014b08ea f77df4???????? idiv??? eax, dword ptr [ebp-0Ch],效果如圖:
              Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試
              我們使用【dp】命令,查看【ebp-0Ch】代碼的值。

1 0:000> dp ebp-0Ch l1
2 012ff2fc  00000000

              我們可以使用【dp】命令,也可以使用【?】命令,查看一下eax 是什么,其實(shí) eax就是十進(jìn)制的10。

1 0:000> ? eax
2 Evaluate expression: 10 = 0000000a

              代碼【idiv】就是表示除法觸發(fā)的異常。
              我們也可以使用【k】命令,查看調(diào)用棧,也能看出在哪里中斷。

1 0:000> k
2  # ChildEBP RetAddr      
3 00 012ff308 014b086b     Example_4_1_3!COM+_Entry_Point <PERF> (Example_4_1_3+0x6308ea) [E:\...\Example_4_1_3\Program.cs @ 18] 
4 01 012ff318 7077f036     Example_4_1_3!COM+_Entry_Point <PERF> (Example_4_1_3+0x63086b) [E:\...\Example_4_1_3\Program.cs @ 9] 
5 ......
6 0f 012ffde4 77057054     ntdll!__RtlUserThreadStart+0x2f
7 10 012ffdf4 00000000     ntdll!_RtlUserThreadStart+0x1b

              紅色部分就是中斷的 C# 代碼的行號。


          2.5、單步調(diào)試命令測試。
              測試代碼:Example_4_1_4
              說明一下,這些測試命令,不需要每個命令建立一個獨(dú)立的測試項(xiàng)目,所以我這里就使用了一個項(xiàng)目做測試。為了更明確,每個命令單獨(dú)測試。但是編譯項(xiàng)目,通過Windbg 加載項(xiàng)目就不詳述了。都是通過 Windbg的【launch executable】附加應(yīng)用程序的,進(jìn)入到的調(diào)試器后,通過【g】命令繼續(xù)運(yùn)行,會在 C# 【Debugger.Break()】代碼出中斷,我們通過【!clrstack】線程棧,找到 Program 的 Main 方法的地址,然后在這個地址上通過【bp】命令下斷點(diǎn),剩下就可以自由調(diào)試了。
1 0:000> !clrstack
2 OS Thread Id: 0x35ec (0)
3 Child SP       IP Call Site
4 00aff270 76e8f262 [HelperMethodFrame: 00aff270] System.Diagnostics.Debugger.BreakInternal()
5 00aff2ec 6fe1f195 System.Diagnostics.Debugger.Break() [f:\dd\ndp\clr\src\BCL\system\diagnostics\debugger.cs @ 91]
6 00aff314 00cc0895 Example_4_1_4.Program.Main(System.String[]) [E:\Visual Studio\...\Example_4_1_4\Program.cs @ 11]
7 00aff4b4 7077f036 [GCFrame: 00aff4b4] 

              在紅色標(biāo)注的地址上設(shè)置斷點(diǎn)。

0:000> bp 00cc0895

              【g】繼續(xù)運(yùn)行。

              Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

              開始調(diào)試了。

              p命令:                  
 1 0:000> p
 2 eax=00000022 ebx=00aff3e4 ecx=0000000a edx=00000000 esi=02ab24bc edi=00aff330
 3 eip=00cc08b3 esp=00aff314 ebp=00aff348 iopl=0         nv up ei pl nz ac pe nc
 4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
 5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x6408b3):
 6 00cc08b3 8945e8          mov     dword ptr [ebp-18h],eax ss:002b:00aff330=00000000
 7 0:000> p
 8 eax=00000022 ebx=00aff3e4 ecx=0000000a edx=00000000 esi=02ab24bc edi=00aff330
 9 eip=00cc08b6 esp=00aff314 ebp=00aff348 iopl=0         nv up ei pl nz ac pe nc
10 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
11 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x6408b6):
12 00cc08b6 b9a8422a6f      mov     ecx,offset mscorlib_ni!GetObjectData+0x102 (6f2a42a8)
13 0:000> p
14 eax=00000022 ebx=00aff3e4 ecx=6f2a42a8 edx=00000000 esi=02ab24bc edi=00aff330
15 eip=00cc08bb esp=00aff314 ebp=00aff348 iopl=0         nv up ei pl nz ac pe nc
16 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
17 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x6408bb):
18 00cc08bb e83428faff      call    00c630f4

              t命令:
 1 0:000> t
 2 eax=00000000 ebx=0053ee2c ecx=0000000a edx=00779910 esi=025224bc edi=0053ed70
 3 eip=023808a7 esp=0053ed54 ebp=0053ed88 iopl=0         nv up ei pl zr na pe nc
 4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
 5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x21e08a7):
 6 023808a7 ff156c4d3302    call    dword ptr ds:[2334D6Ch] ds:002b:02334d6c=02380918
 7 0:000> t
 8 eax=00000000 ebx=0053ee2c ecx=0000000a edx=00779910 esi=025224bc edi=0053ed70
 9 eip=02380918 esp=0053ed50 ebp=0053ed88 iopl=0         nv up ei pl zr na pe nc
10 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
11 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x21e0918):
12 02380918 55              push    ebp

                  效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

                  執(zhí)行【t】命令后,效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試


              pc命令:                  
1 0:000> pc
2 eax=00000000 ebx=00bfee64 ecx=0000000a edx=00f69910 esi=02f124bc edi=00bfedb0
3 eip=014108a7 esp=00bfed94 ebp=00bfedc8 iopl=0         nv up ei pl zr na pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x9b08a7):
6 014108a7 ff156c4d1301    call    dword ptr ds:[1134D6Ch] ds:002b:01134d6c=01410918

                  效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

                  運(yùn)行后的效果,如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試


              tc命令:               
1 0:000> tc
2 eax=00000000 ebx=010fee04 ecx=0000000a edx=013998f0 esi=031424bc edi=010fed50
3 eip=02f708a7 esp=010fed34 ebp=010fed68 iopl=0         nv up ei pl zr na pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x22608a7):
6 02f708a7 ff156c4d5e01    call    dword ptr ds:[15E4D6Ch] ds:002b:015e4d6c=02f70918

                  第一次執(zhí)行【tc】命令,效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

1 0:000> tc
2 eax=0000000a ebx=010fee04 ecx=0000000a edx=0000000b esi=031424bc edi=010fed50
3 eip=02f7095c esp=010fed14 ebp=010fed2c iopl=0         nv up ei pl zr na pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x226095c):
6 02f7095c ff15784d5e01    call    dword ptr ds:[15E4D78h] ds:002b:015e4d78=02f70990

                  第二次執(zhí)行【tc】命令,效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

1 0:000> tc
2 eax=0000000b ebx=010fee04 ecx=0000000a edx=0000000b esi=031424bc edi=010fed50
3 eip=02f709e5 esp=010fece8 ebp=010fed0c iopl=0         nv up ei pl zr na pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x22609e5):
6 02f709e5 ff15844d5e01    call    dword ptr ds:[15E4D84h] ds:002b:015e4d84=02f70a18

                  第三次執(zhí)行【tc】命令,效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試


              pt命令:
                  初始狀態(tài),如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試

                  執(zhí)行了【pt】命令,遇到【ret】就暫停,也就是回到29行。

1 0:000> pt
2 eax=00000022 ebx=010ff29c ecx=0000000a edx=00000000 esi=030624bc edi=010ff1e0
3 eip=015f097a esp=010ff1c0 ebp=010ff1f8 iopl=0         nv up ei pl nz ac pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x97097a):
6 015f097a c3              ret

                  效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試


              tt命令:
                如果我們運(yùn)行【tt】命令,第一暫停會到【Sum3】方法的44行。
1 0:000> tt
2 eax=00000022 ebx=00aff158 ecx=0000000a edx=00000000 esi=02c924bc edi=00aff0a0
3 eip=00e00a4d esp=00aff034 ebp=00aff05c iopl=0         nv up ei pl nz ac pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x730a4d):
6 00e00a4d c20400          ret     4

                  效果如圖:
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試                  

1 0:000> tt
2 eax=00000022 ebx=00aff158 ecx=0000000a edx=00000000 esi=02c924bc edi=00aff0a0
3 eip=00e00a03 esp=00aff060 ebp=00aff07c iopl=0         nv up ei pl nz ac pe nc
4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
5 Example_4_1_4!COM+_Entry_Point <PERF> (Example_4_1_4+0x730a03):
6 00e00a03 c3              ret

                  第二次執(zhí)行【tt】命令,會在Sum2方法的39行暫停,以此類推。
                  Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試文章來源地址http://www.zghlxwxcb.cn/news/detail-736438.html


        
2.6、退出調(diào)試會話
            
這里不需要更多的代碼,也不用專門寫一個測試程序了,所以就直接用 Example_4_1_4 項(xiàng)目,很簡單,就不作圖例了。
              測試代碼:Example_4_1_4

              A、結(jié)束會話,并退出程序
                  使用【q】命令。

              B、結(jié)束會話,程序繼續(xù)運(yùn)行。
                ?
使用【qd】命令。

四、總結(jié)
    
終于寫完了,為什么說是終于,因?yàn)閷戇@一篇文章,不是一天完成的,還要寫文章,記錄操作過程,作圖例,所以時間就長了。今天介紹的是 Windbg 動態(tài)調(diào)試的命令,我們要想讓調(diào)試任務(wù)更容易,掌握這些調(diào)試技巧還是很有必要的。好了,不說了,不忘初心,繼續(xù)努力,希望老天不要辜負(fù)努力的人。

到了這里,關(guān)于Net 高級調(diào)試之四:Windbg 動態(tài)調(diào)試的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Net 高級調(diào)試之十:輕量級代碼生成的調(diào)試

    Net 高級調(diào)試之十:輕量級代碼生成的調(diào)試

    一、簡介 今天是《Net 高級調(diào)試》的第十篇文章。說起來,高級調(diào)試,調(diào)試的內(nèi)容還是挺多的,技巧也不少,但是,要想做一個合格的高級調(diào)試人員,還需要掌握如何調(diào)試動態(tài)生成的IL代碼。今天要探討的高級調(diào)試的技巧是如何調(diào)試通過 Emit 動態(tài)生成 IL 代碼??赡苡腥藭?,

    2024年02月05日
    瀏覽(95)
  • 聊一聊 .NET高級調(diào)試 內(nèi)核模式堆泄露

    聊一聊 .NET高級調(diào)試 內(nèi)核模式堆泄露

    前幾天有位朋友找到我,說他的機(jī)器內(nèi)存在不斷的上漲,但在任務(wù)管理器中查不出是哪個進(jìn)程吃的內(nèi)存,特別奇怪,截圖如下: 在我的分析旅程中都是用戶態(tài)模式的內(nèi)存泄漏,像上圖中的異常征兆已經(jīng)明確告訴你了,不是用戶態(tài)程序吃的內(nèi)存,那就是內(nèi)核態(tài)程序吃的,比如:

    2024年02月04日
    瀏覽(20)
  • Net 高級調(diào)試之九:SOSEX 擴(kuò)展命令介紹

    Net 高級調(diào)試之九:SOSEX 擴(kuò)展命令介紹

    一、介紹 今天是《Net 高級調(diào)試》的第九篇文章。這篇文章設(shè)計(jì)的內(nèi)容挺多的,比如:擴(kuò)展的斷點(diǎn)支持,如何查找元數(shù)據(jù),?;厮荩瑢ο髾z查,死鎖檢測等等,內(nèi)容挺多的。功能特別強(qiáng)大,使用特別方便, 但是需要說明一點(diǎn),這些功能不是 SOS 的功能,是 SOSEX 的擴(kuò)展功能,但

    2024年02月05日
    瀏覽(16)
  • 聊一聊 .NET高級調(diào)試 中的一些內(nèi)存術(shù)語

    聊一聊 .NET高級調(diào)試 中的一些內(nèi)存術(shù)語

    在高級調(diào)試的旅程中,經(jīng)常會有一些朋友問我什么是 工作集(內(nèi)存) ,什么是 提交大小 ,什么是 Virtual Size , 什么是 Working Set 。。。截圖如下: 既然有很多朋友問,這些用口頭也不怎么好描述,剛好上午有時間就系統(tǒng)的聊一下吧。 可能有些朋友知道,內(nèi)存中的虛擬地址被劃分

    2024年02月05日
    瀏覽(20)
  • Net 高級調(diào)試之七:線程操作相關(guān)命令介紹

    Net 高級調(diào)試之七:線程操作相關(guān)命令介紹

    一、簡介 今天是《Net 高級調(diào)試》的第七篇文章。上一篇文章我們說了值類型,引用類型,數(shù)組等的內(nèi)存表現(xiàn)形式。有了這個基礎(chǔ),我們可以更好的了解我們的程序在運(yùn)行時的狀態(tài),內(nèi)存里有什么東西,它們的結(jié)構(gòu)組成是什么樣子的,對我們調(diào)試程序是更有幫助的。今天,我

    2024年02月05日
    瀏覽(17)
  • Net 高級調(diào)試之八:代碼審查及雜項(xiàng)命令

    Net 高級調(diào)試之八:代碼審查及雜項(xiàng)命令

    一、簡介 今天是《Net 高級調(diào)試》的第八篇文章。這篇文章設(shè)計(jì)的內(nèi)容挺多的,比如:如何查看方法的匯編代碼,如何獲取方法的描述符,對象同步塊的轉(zhuǎn)儲,對象方法表的轉(zhuǎn)儲,托管堆和垃圾回收器信息的轉(zhuǎn)儲,CLR 的版本,GC 模式,等等,內(nèi)容挺多的。內(nèi)容雖然挺多,但是

    2024年02月05日
    瀏覽(33)
  • 聊一聊 .NET高級調(diào)試 中必知的符號表

    聊一聊 .NET高級調(diào)試 中必知的符號表

    在高級調(diào)試的旅行中,發(fā)現(xiàn)有不少人對符號表不是很清楚,其實(shí)簡而言之符號表中記錄著一些程序的生物特征,比如哪個地址是函數(shù)(簽名信息),哪個地址是全局變量,靜態(tài)變量,行號是多少,數(shù)據(jù)類型是什么 等等,目的就是輔助我們可視化的調(diào)試,如果沒有這些輔助我們看

    2024年02月05日
    瀏覽(23)
  • Net 高級調(diào)試之五:如何在托管函數(shù)上設(shè)置斷點(diǎn)

    Net 高級調(diào)試之五:如何在托管函數(shù)上設(shè)置斷點(diǎn)

    一、簡介 今天是《Net 高級調(diào)試》的第五篇文章。今天這篇文章開始介紹如何在托管方法和非托管方法設(shè)置斷點(diǎn),我們要想調(diào)試程序,必須掌握調(diào)試的一些命令,動態(tài)調(diào)試的命令,我們在上一篇文章已經(jīng)講過了。光有命令也是不行的,要讓這些調(diào)試命令有用,必須可以在方法

    2024年02月06日
    瀏覽(23)
  • Net 高級調(diào)試之十一:托管堆布局架構(gòu)和對象分配機(jī)制

    Net 高級調(diào)試之十一:托管堆布局架構(gòu)和對象分配機(jī)制

    一、簡介 今天是《Net 高級調(diào)試》的第十一篇文章,這篇文章來的有點(diǎn)晚,因?yàn)?,最近比較忙,就沒時間寫文章了?,F(xiàn)在終于有點(diǎn)時間,繼續(xù)開始我們這個系列。這篇文章我們主要介紹托管堆的架構(gòu),對象的分配機(jī)制,我們?nèi)绾尾檎以谕泄芏焉系膶ο?,我學(xué)完這章,很多以前

    2024年02月05日
    瀏覽(18)
  • Windows安裝WinDbg調(diào)試工具

    Windows安裝WinDbg調(diào)試工具

    微軟官網(wǎng)下載SDK的地址,有win11,win10,win8,win7,其他 https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/ 打開windbgInstallersX64 Debuggers And Tools-x64_en-us.msi 要安裝對應(yīng)系統(tǒng)位數(shù) 不然打不開 安裝完成后沒有反應(yīng)。 開始菜單有 如果找不到可以從右側(cè)路徑找 官網(wǎng) https://www.intel.

    2024年02月05日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包