當前位置:編程學習大全網 - 源碼下載 - Windbg如何設置應用程序的斷點

Windbg如何設置應用程序的斷點

,設置為 cache*d:\symbols;srv*/download/symbols 可以將路徑更改為自己本地的緩存路徑。如果有壹把好梯子的話,設置為全局代理模式,在調試的時候,會將.NET的框架PDB文件下載到該緩存目錄裏,我們在調試的時候就能看到更詳細的信息。

當然,也可以通過命令行來主動獲取微軟官方調試符號。

symchk /r C:\Windows\System32\*.dll /s SRV*D:\symbols\*/download/symbolssymchk C:\WINDOWS\System32\KERNELBASE.dll /s SRV*D:\symbols\*/download/symbols

2、加載正確版本CLR以及SOS(Son of Strike)。

Windbg用戶模式下,調試.Net 應用程序,我們需要正確的加載CLR以及SOS(Son of Strike)。需要註意的是,加載的CLR以及SOS版本壹定要正確。如果應用程序在X86平臺下編譯,則需要加載C:\Windows\Microsoft.NET\Framework\v4.0.30319 目錄下的SOS以及CLR,64位下編譯的話,需要加載C:\Windows\Microsoft.NET\Framework64\v4.0.30319目錄下的SOS以及CLR。2.0的程序需要加載MSCORWKS。

3、例子

以壹個簡單的Demo為例,來看壹下如何在Windbg中設置斷點。(在4.0FrameWork、X86平臺下編譯)。這個程序,根據體重身高來計算BMI指數,假定BMI指數為21的為最健康的,對給定的人員列表按照偏差大小的絕對值進行排序。讓我們姑且認為偏差越小身體越健康吧。

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Text;

5

6 namespace WindbugDemo

7 {

8 public class Person

9 {

10 //認為BMI和21偏差最小的為最健康的

11 private const double BmiHelthConst = 21f;

12

13 public string Name { get; set; }

14 public int Age { get; set; }

15 public double Height { get; set; }

16 public double Weight { get; set; }

17 public double BmiVariance { get { return GetBmiVariance(); } }

18 //18歲至65歲可以Weight/(Height*Height)計算,否則拋出異常

19 public double GetBmiVariance()

20 {

21 if (Age > 65 || Age < 18)

22 throw new Exception("18歲以下65歲以上人群不適用此計算方法");

23 double bmi = Math.Round(Weight / Math.Pow(Height, 2),2);

24 double variance = Math.Abs(bmi - BmiHelthConst);

25 return variance;

26 }

27 }

28

29 public class HelthCompare : IComparer<Person>

30 {

31 public int Compare(Person x, Person y)

32 {

33

34 double diffx = x.BmiVariance;

35 double diffy = y.BmiVariance;

36 if (diffx == diffy)

37 return 0;

38 if (diffx > diffy)

39 return 1;

40 return -1;

41 }

42 }

43

44 class Health

45 {

46 [STAThread]

47 static void Main(string[] args)

48 {

49 Person person1 = new Person { Name = "James", Age = 35, Height = 1.70, Weight = 70 };

50 Person person2 = new Person { Name = "Tony", Age = 25, Height = 1.65, Weight = 60 };

51 Person person3 = new Person { Name = "John", Age = 30, Height = 1.75, Weight = 90 };

52 Person[] array = new Person[] { person1, person2, person3 };

53 List<Person> list = new List<Person>();

54 list.AddRange(array);

55 HelthCompare comparer = new HelthCompare();

56 list.Sort(comparer);

57 foreach(var item in list)

58 {

59 string text = string.Format("Name:{0} Age:{1} Height:{2} Weight:{3} BMI Variance:{4}",

60 item.Name,item.Age, item.Height, item.Weight, item.BmiVariance);

61 System.Console.WriteLine(text);

62 }

63 Console.ReadKey();

64 /*

65 Name:Tony Age:25 Height:1.65 Weight:60 BMI Variance:1.04

66 Name:James Age:35 Height:1.7 Weight:70 BMI Variance:3.22

67 Name:John Age:30 Height:1.75 Weight:90 BMI Variance:8.39

68 */

69 }

70 }

71

72 }

3.1 打開Windbg,在File==》Open Executable...打開編譯後的程序。指定PDB路徑以及源碼路徑。

0:000> .sympath+ d:\source

Symbol search path is: cache*d:\symbols;srv*/download/symbols;d:\source

Expanded Symbol search path is: cache*d:\symbols;srv*/download/symbols;d:\source

Source search path is: d:\source

0:000> .reload

Reloading current modules

.....

3.2 可以使用 sxe ld:clrjit 命令,這個命令發生在clrjit加載的時候,在進入Main方法之前,這對於我們設置自己程序的斷點很方便。然後輸入g命令,當加載clrjit的時候,就可以命中斷點了。

0:000> sxe ld:clrjit

0:000> g

(cc8.cd0): Unknown exception - code 04242420 (first chance)

ModLoad: 6d110000 6d18d000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll

eax=00000000 ebx=00000000 ecx=001437a4 edx=00000001 esi=7ffdf000 edi=0027e340

eip=76df70b4 esp=0027e258 ebp=0027e2ac iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

ntdll!KiFastSystemCallRet:

76df70b4 c3 ret

0:000> .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll

0:000> .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll

0:000> .loadby sos clr (等同於上面兩條命令)

3.3 加載完SOS後,就可以用擴展命令來設置斷點了。

0:000> !name2ee Health!WindbugDemo.Health

Module: 00142edc

Assembly: Health.exe

Token: 02000004

MethodTable: 001437b8

EEClass: 00141304

Name: WindbugDemo.Health

0:000> !dumpmt -md 001437b8

EEClass: 00141304

Module: 00142edc

Name: WindbugDemo.Health

mdToken: 02000004

File: D:\bin\Health.exe

BaseSize: 0xc

ComponentSize: 0x0

Slots in VTable: 6

Number of IFaces in IFaceMap: 0

--------------------------------------

MethodDesc Table

Entry MethodDe JIT Name

6647952c 6619612c PreJIT System.Object.ToString()

6648ec30 66196134 PreJIT System.Object.Equals(System.Object)

6648e860 66196154 PreJIT System.Object.GetHashCode()

6648e2a0 66196168 PreJIT System.Object.Finalize()

0014c015 001437b0 NONE WindbugDemo.Health..ctor()

0014c011 001437a4 NONE WindbugDemo.Health.Main(System.String[])

0:000> !dumpmt -md 001437b8

EEClass: 00141304

Module: 00142edc

Name: WindbugDemo.Health

mdToken: 02000004

File: D:\bin\Health.exe

BaseSize: 0xc

ComponentSize: 0x0

Slots in VTable: 6

Number of IFaces in IFaceMap: 0

--------------------------------------

MethodDesc Table

Entry MethodDe JIT Name

6647952c 6619612c PreJIT System.Object.ToString()

6648ec30 66196134 PreJIT System.Object.Equals(System.Object)

6648e860 66196154 PreJIT System.Object.GetHashCode()

6648e2a0 66196168 PreJIT System.Object.Finalize()

0014c015 001437b0 NONE WindbugDemo.Health..ctor()

0014c011 001437a4 NONE WindbugDemo.Health.Main(System.String[])

0:000> !bpmd -md 001437a4

MethodDesc = 001437a4

Adding pending breakpoints...

在上面的Windbg調試窗口裏,JIT為NONE的就表示還沒有進行JIT編譯。這種情況下,我們不能使用bp命令來設置斷點的。我們可以使用bpmd命令加md參數來設置斷點。輸入g命令程序繼續執行。

0:000> !u 001437a4

Normal JIT generated code

WindbugDemo.Health.Main(System.String[])

Begin 011f0050, size 5cc

d:\source\02Health\Health.cs @ 48:

011f0050 55 push ebp

011f0051 8bec mov ebp,esp

... ...

d:\source\02Health\Health.cs @ 56:

011f0377 8b8d68ffffff mov ecx,dword ptr [ebp-98h]

011f037d 8b9564ffffff mov edx,dword ptr [ebp-9Ch]

011f0383 3909 cmp dword ptr [ecx],ecx

011f0385 e822022b65 call mscorlib_ni+0x3105ac (664a05ac) (System.Collections.Generic.List`1[[System.__Canon, mscorlib]].Sort(System.Collections.Generic.IComparer`1<System.__Canon>), mdToken: 06002283)

011f038a 90 nop

... ...

0:000> bp 011f0377

0:000> g

3.4 對於已經JIT編譯的方法,我們可以采用u命令,查看反匯編,然後就可以在對應的行號用非托管應用程序的bp命令來設置斷點了。

以上兩種方法可以在Windbg下設置斷點。查找方法表還可以根據domain信息查找Module信息

0:000> !dumpdomain

--------------------------------------

System Domain: 67840f60

LowFrequencyHeap: 67841284

HighFrequencyHeap: 678412cc

StubHeap: 67841314

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 67840c08

LowFrequencyHeap: 67841284

HighFrequencyHeap: 678412cc

StubHeap: 67841314

Stage: OPEN

Name: None

Assembly: 003b24f0 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]

ClassLoader: 003b25b8

Module Name

66191000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

--------------------------------------

Domain 1: 00364d50

LowFrequencyHeap: 003651a4

HighFrequencyHeap: 003651ec

StubHeap: 00365234

Stage: OPEN

SecurityDescriptor: 00366920

Name: Health.exe

Assembly: 003b24f0 [C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]

ClassLoader: 003b25b8

SecurityDescriptor: 003af690

Module Name

66191000 C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly: 003bfbd8 [D:\bin\Health.exe]

ClassLoader: 003bfca0

SecurityDescriptor: 003bf880

Module Name

00142edc D:\bin\Health.exe

0:000> !dumpmodule -mt 00142edc

Name: D:\bin\Health.exe

Attributes: PEFile

Assembly: 003bfbd8

LoaderHeap: 00000000

TypeDefToMethodTableMap: 00140038

TypeRefToMethodTableMap: 0014004c

MethodDefToDescMap: 0014009c

FieldDefToDescMap: 001400dc

MemberRefToDescMap: 00000000

FileReferencesMap: 001400f8

AssemblyReferencesMap: 001400fc

MetaData start address: 0123237c (2360 bytes)

Types defined in this module

MT TypeDef Name

------------------------------------------------------------------------------

001437b8 0x02000004 WindbugDemo.Health

Types referenced in this module

MT TypeRef Name

------------------------------------------------------------------------------

665941b8 0x02000001 System.Object

0:000> !dumpmt -md 001437b8

EEClass: 00141304

Module: 00142edc

Name: WindbugDemo.Health

mdToken: 02000004

File: D:\bin\Health.exe

BaseSize: 0xc

ComponentSize: 0x0

Slots in VTable: 6

Number of IFaces in IFaceMap: 0

--------------------------------------

MethodDesc Table

Entry MethodDe JIT Name

6647952c 6619612c PreJIT System.Object.ToString()

6648ec30 66196134 PreJIT System.Object.Equals(System.Object)

6648e860 66196154 PreJIT System.Object.GetHashCode()

6648e2a0 66196168 PreJIT System.Object.Finalize()

0014c015 001437b0 NONE WindbugDemo.Health..ctor()

0014c011 001437a4 NONE WindbugDemo.Health.Main(System.String[])

3.5 也可以通過JIT編譯的代碼地址來設置斷點。

0:000> !name2ee Health!Win

  • 上一篇:通用表單源代碼
  • 下一篇:8款壓箱底的微信小程序,全是黑科技,用起來超爽
  • copyright 2024編程學習大全網