Windbg在Managed App中设置函数断点的几种方法
本文介紹兩種使用Windbg在Managed App中設(shè)置斷點(diǎn)的方法。一種是在live Debug的時(shí)候,attach到了Process之后。另外一種是動(dòng)態(tài)調(diào)試的時(shí)候,如何給幾個(gè)模塊的特定方法下一個(gè)斷點(diǎn)。????
???????? 使用Windbg在Native Code里面下斷點(diǎn)是比較方便的,bp加上一個(gè)內(nèi)存地址就可以做到。但是在托管的時(shí)候給一個(gè)方法下一個(gè)斷點(diǎn)稍微有點(diǎn)麻煩。因?yàn)?/span>Windbg是一個(gè)native Debugger,而Managed App在沒有Jited的時(shí)候,是沒有生成Native Code的。每個(gè)方法在第一次調(diào)用之后,才生成了native code。當(dāng)然,這里不說ngen。
????????
???????? 還是先給個(gè)小程序做小白鼠:
???????? class Program
??? {
??????? static void Main(string[] args)
??????? {
??????????? System.Console.WriteLine("Show Params in Windbg");
??????????? Program p = new Program();
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
?
??????????? p.ShowParams(123456, "TestParams", 'L');
?
??????????? System.Console.ReadLine();
??????? }
??????? public void ShowParams(int a, string b ,char c)
??????? {
??????? }
}
?????????
????????? 在使用live Debug的時(shí)候,設(shè)置一個(gè)沒有本地代碼的方法斷點(diǎn)不是很麻煩,首先:
?
????????? 0:000> !name2ee *!FounctionParams.Program
Module: 790c2000 (mscorlib.dll)
--------------------------------------
Module: 00a82c3c (FounctionParams.exe)
Token: 0x02000002
MethodTable: 00a83038
EEClass: 00a811d8
Name: FounctionParams.Program
?
得到了MethodTable的地址了,然后:
?????????
0:000> !dumpmt -md 00a83038
EEClass: 00a811d8
Module: 00a82c3c
Name: FounctionParams.Program
mdToken: 02000002? (E:\myProject\FounctionParams\FounctionParams\bin\Debug\FounctionParams.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 7
--------------------------------------
MethodDesc Table
?? Entry MethodDesc????? JIT Name
79371278?? 7914b928?? PreJIT System.Object.ToString()
7936b3b0?? 7914b930?? PreJIT System.Object.Equals(System.Object)
7936b3d0?? 7914b948?? PreJIT System.Object.GetHashCode()
793624d0?? 7914b950?? PreJIT System.Object.Finalize()
00db0070?? 00a83020????? JIT FounctionParams.Program.Main(System.String[])
00db0110?? 00a83028????? JIT FounctionParams.Program.ShowParams
(Int32, System.String, Char)
00db00e0?? 00a83030????? JIT FounctionParams.Program..ctor()
?
這里,得到了這個(gè)方法的MethodDesc的地址之后,繼續(xù):
0:000> !dumpmd 00a83028?????
Method Name: FounctionParams.Program.ShowParams(Int32, System.String, Char)
Class: 00a811d8
MethodTable: 00a83038
mdToken: 06000002
Module: 00a82c3c
IsJitted: yes
m_CodeOrIL: 00db0110
?
可以看到,已經(jīng)JIT過了,生成了本地的代碼。列個(gè)時(shí)候,就有很多選擇了,順便看看native code:
0:000> !u 00db0110
Normal JIT generated code
FounctionParams.Program.ShowParams(Int32, System.String, Char)
Begin 00db0110, size 20
>>> 00db0110 83ec08?????? ???sub???? esp,8
00db0113 890c24????????? mov???? dword ptr [esp],ecx
00db0116 89542404??????? mov???? dword ptr [esp+4],edx
00db011a 833d082ea80000? cmp???? dword ptr ds:[0A82E08h],0
00db0121 7405??????????? je????? 00db0128
00db0123 e81f823779????? call ???mscorwks!JIT_DbgIsJustMyCode (7a128347)
00db0128 90????????????? nop
00db0129 90????????????? nop
00db012a 83c408????????? add???? esp,8
00db012d c20800????????? ret???? 8
?
感覺和方法本身的代碼不是很像,不過也就是他了,這個(gè)時(shí)候下斷點(diǎn)可以有很多選擇:
在地址上面下斷點(diǎn):
0:000> bp 00db0110
用BPMD命令在這個(gè)方法的MethodDesc上面下斷點(diǎn):
0:000> !bpmd -md 00a83028?????
MethodDesc = 00a83028
Setting breakpoint: bp 00DB0110 [FounctionParams.Program.ShowParams(Int32, System.String, Char)]
?
That will work。
?
如果是動(dòng)態(tài)調(diào)試下面,該如何做呢?這個(gè)比較麻煩點(diǎn):
使用Windbg的Open Executable File菜單,打開上面編寫的測試的引用程序:
0:000> sxe ld:mscorjit
0:000> g
ModLoad: 79060000 790b6000?? C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll
eax=00000000 ebx=00000000 ecx=00d90000 edx=7c90eb94 esi=00000000 edi=00000000
eip=7c90eb94 esp=0012e554 ebp=0012e648 iopl=0 nv up ei ng nz ac pe nc
cs=001b? ss=0023? ds=0023? es=0023? fs=003b? gs=0000 efl=00000296
ntdll!KiFastSystemCallRet:
7c90eb94 c3????????????? ret
?
接著查看線程:
?
0:000> !threads
ThreadCount: 2
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
?
Hosted Runtime: no
????????????????????????????????????? PreEmptive?? GC Alloc??????????
?????? ID?????? Context?????? Domain?? Count APT Exception
?? 0??? 1?? 013f16d0:013f1fe8 0015c410? ???2 MTA
?? 2??? 2?? 00000000:00000000 0015c410 ????0 MTA (Finalizer)
?
接著就查看這個(gè)domain:
?
0:000> !dumpdomain 0015c410????
--------------------------------------
Domain 1: 0015c410
LowFrequencyHeap: 0015c434
HighFrequencyHeap: 0015c48c
StubHeap: 0015c4e4
Stage: OPEN
SecurityDescriptor: 0015d740
Name: FounctionParams.exe
Assembly: 0019f408
[C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader: 0019f4a0
SecurityDescriptor: 0019be58
? Module Name
790c2000
C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll
?
Assembly: 001a6b90
[E:\myProject\FounctionParams\FounctionParams\bin\Debug\FounctionParams.exe]
ClassLoader: 001a7270
SecurityDescriptor: 001a6a58
? Module Name
00a82c3c
E:\myProject\FounctionParams\FounctionParams\bin\Debug\FounctionParams.exe
?
然后查看module的信息:
?
0:000> !dumpmodule -mt 00a82c3c
Name: E:\myProject\FounctionParams\FounctionParams\bin\Debug\FounctionParams.exe
Attributes: PEFile
Assembly: 001a6b90
LoaderHeap: 00000000
TypeDefToMethodTableMap: 00a80038
TypeRefToMethodTableMap: 00a80040
MethodDefToDescMap: 00a8008c
FieldDefToDescMap: 00a8009c
MemberRefToDescMap: 00a800a0
FileReferencesMap: 00a800ec
AssemblyReferencesMap: 00a800f0
MetaData start address: 00402094 (1580 bytes)
?
Types defined in this module
?
????? MT??? TypeDef Name
------------------------------------------------------------------------------
00a83038 0x02000002 FounctionParams.Program
?
Types referenced in this module
?
????? MT??? TypeRef Name
------------------------------------------------------------------------------
790fd0f0 0x01000001 System.Object
?
恩,找到MT的地址了:
?
0:000> !dumpmt -md 00a83038
EEClass: 00a811d8
Module: 00a82c3c
Name: FounctionParams.Program
mdToken: 02000002? (E:\myProject\FounctionParams\FounctionParams\bin\Debug\FounctionParams.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 7
--------------------------------------
MethodDesc Table
?? Entry MethodDesc????? JIT Name
79371278?? 7914b928? ?PreJIT System.Object.ToString()
7936b3b0?? 7914b930?? PreJIT System.Object.Equals(System.Object)
7936b3d0?? 7914b948?? PreJIT System.Object.GetHashCode()
793624d0?? 7914b950?? PreJIT System.Object.Finalize()
00a8c011?? 00a83020???? NONE FounctionParams.Program.Main(System.String[])
00a8c015?? 00a83028???? NONE FounctionParams.Program.ShowParams
(Int32, System.String, Char)
00a8c019?? 00a83030???? NONE FounctionParams.Program..ctor()
?
恩,這個(gè)時(shí)候還沒有被JIT,正好可以在這個(gè)地方下一個(gè)斷點(diǎn),當(dāng)執(zhí)行到這個(gè)方法的時(shí)候就觸發(fā)斷點(diǎn):
0:000> !bpmd -md 00a83028????
MethodDesc = 00a83028????
Adding pending breakpoints...
?
恩,到這個(gè)地方,就給這個(gè)managed的方法,而且是沒jited的給加上了一個(gè)斷點(diǎn)。恩,兩種不同的情況下下斷點(diǎn)的方法。
?
Friday, October 17, 2008 6:35:12 PM
First Post at http://SSCLI.cnblogs.com
轉(zhuǎn)載于:https://www.cnblogs.com/lbq1221119/archive/2008/10/17/1313677.html
總結(jié)
以上是生活随笔為你收集整理的Windbg在Managed App中设置函数断点的几种方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何安装仿宋GB2312字体
- 下一篇: VoIP通话之SIP协议