當然,妳也可以通過命令行主動獲取微軟官方調試符號。
symchk /r C:\Windows\System32\*。dll/s SRV * D:\ symbols \ */download/symbols symchk C:\ WINDOWS \ System32 \ kernel base . dll/s SRV * D:\ symbols \ */download/symbols
2.加載正確版本的CLR和SOS(罷工之子)。
來調試。在Windbg用戶模式下,我們需要正確地加載CLR和SOS。需要註意的是,加載的CLR和SOS版本必須正確。目錄c: \ windows \ Microsoft中的SOS和CLR。如果是在X86平臺下編譯應用,需要加載net \ framework \ v4.0.30319,C: \ windows \ Microsoft。net \ framework 64 \ v 4 . 0 . 30365438 . 30366666664 2.0程序需要加載MSCORWKS。
3.例子
以壹個簡單的演示為例,看看如何在Windbg中設置斷點。(在4.0框架和X86平臺下編譯)。這個程序根據體重和身高計算身體質量指數指數,假設身體質量指數為21的那個最健康,並根據偏差的絕對值對給定的人員名單進行排序。這麽說吧,偏差越小,身體越健康。
1使用系統;
2使用系統。集合。泛型;
3使用系統。Linq
4使用系統。文本;
五
6命名空間WindbugDemo
7 {
8公開課人
9 {
10 //認為身體質量指數和21的偏差最小是最健康的。
11 private const double BmiHelthConst = 21f;
12
13公共字符串名稱{ get設置;}
14 public int Age { get;設置;}
15公立雙高{ get設置;}
16公雙重{ get設置;}
17 public double BMI variance { get { return getbmi variance();} }
18 //18到65歲可以按體重/(身高*身高)計算,否則會拋出異常。
19 public double getbmi variance()
20 {
21 if(年齡& gt65 ||年齡& lt18)
22拋出新異常(“此計算方法不適用於18以下及65歲以上人群”);
23雙bmi =數學。四舍五入(重量/數學。Pow(高度,2),2);
24雙方差=數學。ABS(BMI-BMI helthconst);
25返回差異;
26 }
27 }
28
29公共類helth compare:I comparer & lt;Person & gt
30 {
31公共int比較(人x,人y)
32 {
33
34 double diffx = x . BmiVariance
35 double diffy = y . BmiVariance
36 if(difx = = diffy)
37返回0;
38 if(diffx & gt;diffy)
39返回1;
40 return-1;
41 }
42 }
43
44類健康
45 {
46[斯塔特螺紋]
47靜態void Main(string[] args)
48 {
49人person1 =新人{ Name = "James ",年齡= 35,身高= 1.70,體重= 70 };
50人person2 =新人{ Name = "Tony ",年齡= 25,身高= 1.65,體重= 60 };
51人person3 =新人{ Name = "John ",年齡= 30,身高= 1.75,體重= 90 };
52人[]數組=新人[] {人員1,人員2,人員3 };
53列表& ltPerson & gtlist =新列表& ltPerson & gt();
54列表。AddRange(數組);
55 HelthCompare comparer = new HelthCompare();
56列表。排序(比較器);
57 foreach(列表中的變量項)
58 {
59字符串文本=字符串。Format("姓名:{0}年齡:{1}身高:{2}體重:{3}身體質量指數方差:{4} ",
60項。名稱,項目。年齡,物品。高度,項目。重量,項目。BMI variance);
61系統。Console.WriteLine(文本);
62 }
63控制臺。read key();
64 /*
65姓名:托尼年齡:25身高:1.65體重:60身體質量指數方差:1.04
66姓名:詹姆斯年齡:35身高:1.7體重:70身體質量指數方差:3.22
67姓名:約翰年齡:30身高:1.75體重:90身體質量指數方差:8.39
68 */
69 }
70 }
71
72 }
3.1打開Windbg,打開file = = "Open Executable ... "中編譯好的程序。。指定PDB路徑和源代碼路徑。
0:000 & gt;。交感+ d:\source
符號搜索路徑為:cache * d:\ symbols;SRV */download/symbols;d:\source
擴展的符號搜索路徑是:cache * d:\ symbols;SRV */download/symbols;d:\source
源搜索路徑是:d:\source
0:000 & gt;。再裝
重新加載當前模塊
.....
3.2我們可以使用sxe ld:clrjit命令,該命令在加載clrjit時出現,方便我們在進入Main方法之前設置自己程序的斷點。然後輸入g命令,加載clrjit的時候就可以打到斷點了。
0:000 & gt;sxe ld:clrjit
0:000 & gt;g
(cc8.cd0):未知異常-代碼04242420(第壹次機會)
ModLoad:6d 110000 6d 18d 000 C:\ Windows \ Microsoft。NET \ Framework \ v 4 . 0 . 30319 \ clr JIT . dll
eax = 00000000 ebx = 00000000 ecx = 001437 a4 EDX = 0000001 ESI = 7 ffdf 000 EDI = 0027 e340
EIP = 76df 70 b 4 esp = 0027 e258 ebp = 0027 e2ac iopl = 0 NV up ei pl Zr na PE NC
cs = 001b ss = 0023 ds = 0023 es = 0023 fs = 003 b GS = 0000 EFL = 00000246
ntdll!KiFastSystemCallRet:
76df70b4 c3 ret
0:000 & gt;。加載C:\Windows\Microsoft。NET \ Framework \ v 4 . 0 . 30319 \ SOS . dll
0:000 & gt;。加載C:\Windows\Microsoft。NET \ Framework \ v 4 . 0 . 30319 \ clr . dll
0:000 & gt;。loadby sos clr(相當於上面兩個命令)
3.3加載SOS後,可以使用擴展命令設置斷點。
0:000 & gt;!名2ee健康!WindbugDemo。健康
模塊:00142edc
裝配:Health.exe
令牌:02000004
方法表:001437b8
EEClass: 00141304
名稱:WindbugDemo。健康
0:000 & gt;!dumpmt -md 001437b8
EEClass: 00141304
模塊:00142edc
名稱:WindbugDemo。健康
mdToken: 02000004
文件:D:\bin\Health.exe
BaseSize: 0xc
組件大小:0x0
虛擬表中的插槽:6
IFaceMap中的IFaces數量:0
-
方法描述表
輸入方法JIT名稱
6647952c 6619612c預IT系統。Object.ToString()
6648 EC 30 66196134 pre JIT系統。Object.Equals(System。對象)
6648 e860 66196154 pre JIT系統。Object.GetHashCode()
6648 e2a 0 66196168 pre JIT系統。Object.Finalize()
0014c 015 001437 B0 NONE WindbugDemo。健康..ctor()
0014c 011 001437 a4無WindbugDemo。健康。主要(系統。String[])
0:000 & gt;!dumpmt -md 001437b8
EEClass: 00141304
模塊:00142edc
名稱:WindbugDemo。健康
mdToken: 02000004
文件:D:\bin\Health.exe
BaseSize: 0xc
組件大小:0x0
虛擬表中的插槽:6
IFaceMap中的IFaces數量:0
-
方法描述表
輸入方法JIT名稱
6647952c 6619612c預IT系統。Object.ToString()
6648 EC 30 66196134 pre JIT系統。Object.Equals(System。對象)
6648 e860 66196154 pre JIT系統。Object.GetHashCode()
6648 e2a 0 66196168 pre JIT系統。Object.Finalize()
0014c 015 001437 B0 NONE WindbugDemo。健康..ctor()
0014c 011 001437 a4無WindbugDemo。健康。主要(系統。String[])
0:000 & gt;!bpmd -md 001437a4
MethodDesc = 001437a4
添加掛起的斷點...
在上面的Windbg調試窗口中,JIT為NONE意味著沒有執行JIT編譯。在這種情況下,我們不能使用bp命令來設置斷點。我們可以使用bpmd命令加上md參數來設置斷點。輸入g命令繼續執行。
0:000 & gt;!u 001437a4
正常JIT生成的代碼
WindbugDemo。健康。主要(系統。String[])
Begin 011f0050,尺寸5cc
d:\ source \ 02 health \ health . cs @ 48:
011f0050 55推送ebp
011f 0051 8 bec mov ebp,esp
......
d:\ source \ 02 health \ health . cs @ 56:
011f 0377 8 b 8d 68 ffffff mov ecx,dword ptr [ebp-98h]
011f 037d 8b 9564 ffffff mov EDX,dword ptr [ebp-9Ch]
011f 0383 3909 CMP dword ptr[ecx],ecx
011f0385 e822022b65調用mscorlib _ ni+0x 3105 AC(664 a 05 AC)(系統。collections . generic . list ` 1[[System ._ _佳能,mscorlib]]。排序(系統。collections . generic . I comparer ` 1 & lt;系統。_ _佳能& gt),mdToken: 06002283)
011f038a 90無
......
0:000 & gt;bp 011f0377
0:000 & gt;g
3.4對於JIT編譯的方法,我們可以使用u命令查看反匯編,然後可以使用非托管應用的bp命令在相應的行號設置斷點。
以上兩種方法都可以在Windbg下設置斷點。搜索方法表還可以根據域信息搜索模塊信息。
0:000 & gt;!轉儲域
-
系統域:67840f60
低頻堆:67841284
高頻堆:678412cc
StubHeap: 67841314
階段:打開
名稱:無
-
共享域:67840c08
低頻堆:67841284
高頻堆:678412cc
StubHeap: 67841314
階段:打開
名稱:無
程序集:003b24f0 [C:\Windows\Microsoft。net \ assembly \ GAC _ 32 \ mscorlib \ v 4.0 _ 4 . 0 . 0 . 0 _ _ b 77 a5 c 561934 e 089 \ mscorlib . dll]
類加載器:003b25b8
模塊名
66191000 C:\ Windows \ Microsoft。net \ assembly \ GAC _ 32 \ mscorlib \ v 4.0 _ 4 . 0 . 0 . 0 _ _ b 77 a5 c 561934 e 089 \ mscorlib . dll
-
域名1: 00364d50
低頻堆:003651a4
高頻堆:003651ec
StubHeap: 00365234
階段:打開
安全描述符:00366920
姓名:Health.exe
程序集:003b24f0 [C:\Windows\Microsoft。net \ assembly \ GAC _ 32 \ mscorlib \ v 4.0 _ 4 . 0 . 0 . 0 _ _ b 77 a5 c 561934 e 089 \ mscorlib . dll]
類加載器:003b25b8
安全描述符:003af690
模塊名
66191000 C:\ Windows \ Microsoft。net \ assembly \ GAC _ 32 \ mscorlib \ v 4.0 _ 4 . 0 . 0 . 0 _ _ b 77 a5 c 561934 e 089 \ mscorlib . dll
程序集:003bfbd8 [D:\bin\Health.exe]
類加載器:003bfca0
安全描述符:003bf880
模塊名
00142 EDC D:\ bin \ health . exe
0:000 & gt;!轉儲模塊-mt 00142edc
姓名:D:\bin\Health.exe
屬性:PEFile
組件:003bfbd8
LoaderHeap: 00000000
typedefmethodtablemap:00140038
TypeRefToMethodTableMap:0014004 c
方法DefToDescMap: 0014009c
FieldDefToDescMap:001400 DC
memberref descmap:00000000
filereferencemap:001400 F8
AssemblyReferencesMap:001400 fc
元數據起始地址:0123237c (2360字節)
此模塊中定義的類型
MT TypeDef名稱
-
001437 b8 0x 02000004 WindbugDemo。健康
此模塊中引用的類型
MT TypeRef名稱
-
665941b8 0x02000001系統。目標
0:000 & gt;!dumpmt -md 001437b8
EEClass: 00141304
模塊:00142edc
名稱:WindbugDemo。健康
mdToken: 02000004
文件:D:\bin\Health.exe
BaseSize: 0xc
組件大小:0x0
虛擬表中的插槽:6
IFaceMap中的IFaces數量:0
-
方法描述表
輸入方法JIT名稱
6647952c 6619612c預IT系統。Object.ToString()
6648 EC 30 66196134 pre JIT系統。Object.Equals(System。對象)
6648 e860 66196154 pre JIT系統。Object.GetHashCode()
6648 e2a 0 66196168 pre JIT系統。Object.Finalize()
0014c 015 001437 B0 NONE WindbugDemo。健康..ctor()
0014c 011 001437 a4無WindbugDemo。健康。主要(系統。String[])
3.5斷點也可以通過JIT編譯的代碼地址來設置。
0:000 & gt;!名2ee健康!勝利