Hi all,
This post is a continuation of MANAGED DEBUGGING with WINDBG. Preparing the Environment.
SETTING A BREAKPOINT. Part 1
We can only set breakpoints when doing live debugging, but many of the commands explained here can be used when doing dump analysis, too.
· We find the method where we want to set the breakpoint:
If we don’t know the name of the module, class or method we need, we can do the following:
0:004> !DumpDomain
...
--------------------------------------
Domain 1: 00094bd8
LowFrequencyHeap: 00094bfc
HighFrequencyHeap: 00094c54
StubHeap: 00094cac
Stage: OPEN
SecurityDescriptor: 00095938
Name: WindowsApplication1.exe
Assembly: 000d9748 [C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader: 0008d348
SecurityDescriptor: 000d6568
Module Name
790c2000 C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll
007823dc C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\sortkey.nlp
00782050 C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\sorttbls.nlp
Assembly: 000e4ba0 [C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe]
ClassLoader: 0008d658
SecurityDescriptor: 000e4b18
Module Name
00762c3c C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe
...
0:004> !DumpAssembly 000e4ba0
Parent Domain: 00094bd8
Name: C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe
ClassLoader: 0008d658
SecurityDescriptor: 00843678
Module Name
00762c3c C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe
0:004> !DumpModule -mt 00762c3c
Name: C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe
Attributes: PEFile
Assembly: 000e4ba0
LoaderHeap: 00000000
TypeDefToMethodTableMap: 007600c0
TypeRefToMethodTableMap: 007600ec
MethodDefToDescMap: 0076024c
FieldDefToDescMap: 00760344
MemberRefToDescMap: 007603a0
FileReferencesMap: 007605bc
AssemblyReferencesMap: 007605c0
MetaData start address: 01123128 (10832 bytes)
Types defined in this module
MT TypeDef Name
------------------------------------------------------------------------------
00763dbc 0x02000002 WindowsApplication1.My.MyApplication
00765e74 0x02000003 WindowsApplication1.My.MyComputer
00765c48 0x02000004 WindowsApplication1.My.MyProject
007661f4 0x02000005 WindowsApplication1.My.MyProject+MyForms
00766330 0x02000006 WindowsApplication1.My.MyProject+MyWebServices
00765de0 0x02000007 WindowsApplication1.My.MyProject+ThreadSafeObjectProvider`1
00766e94 0x02000008 WindowsApplication1.Form1
Types referenced in this module
MT TypeRef Name
------------------------------------------------------------------------------
5e4e3d4c 0x01000001 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
79104368 0x01000002 System.Collections.ArrayList
...
0:004> !DumpMT -md 00766e94
EEClass: 00ed0a30
Module: 00762c3c
Name: WindowsApplication1.Form1
mdToken: 02000008 (C:\ __MANAGED DEBUGGING\BuggyNETApp\bin\Debug\WindowsApplication1.exe)
BaseSize: 0x158
ComponentSize: 0x0
Number of IFaces in IFaceMap: 15
Slots in VTable: 395
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
7b05e348 7b4a4668 PreJIT System.Windows.Forms.Form.ToString()
...
7b068b6c 7b4a4680 PreJIT System.Windows.Forms.Form.OnResizeEnd(System.EventArgs)
00851638 00766d68 JIT WindowsApplication1.Form1.get_Button1()
...
0076c2d8 00766d60 JIT WindowsApplication1.Form1.InitializeComponent()
0076c1b4 00766e08 NONE WindowsApplication1.Form1.CopyMem(IntPtr, IntPtr, Int64)
0076c2ec 00766db8 NONE WindowsApplication1.Form1.Button1_Click(System.Object, System.EventArgs)
...
Now, the method we choose can be jitted (.NET compiles IL to asm when we are going to use a method for the first time - Just In Time-)/pre-jitted, or not:
0:004> !DumpMD 00766d60
Method Name: WindowsApplication1.Form1.InitializeComponent()
Class: 00ed0a30
MethodTable: 00766e94
mdToken: 06000021
Module: 00762c3c
IsJitted: yes
m_CodeOrIL: 00850a08
0:004> !DumpMD 00766db8
Method Name: WindowsApplication1.Form1.Button1_Click(System.Object, System.EventArgs)
Class: 00ed0a30
MethodTable: 00766e94
mdToken: 0600002d
Module: 00762c3c
IsJitted: no
m_CodeOrIL: ffffffff
If we know the name of the method and in which module we can find it, we can get the method descriptor and jitted address directly like this:
0:004> !Name2EE WindowsApplication1!WindowsApplication1.Form1.InitializeComponent
...
0:004> !Name2EE WindowsApplication1 WindowsApplication1.Form1.InitializeComponent
Module: 00762c3c (WindowsApplication1.exe)
Token: 0x06000021
MethodDesc: 00766d60
Name: WindowsApplication1.Form1.InitializeComponent()
JITTED Code Address: 00850a08
0:004> !Name2EE WindowsApplication1 WindowsApplication1.Form1.Button1_Click
Module: 00762c3c (WindowsApplication1.exe)
Token: 0x0600002d
MethodDesc: 00766db8
Name: WindowsApplication1.Form1.Button1_Click(System.Object, System.EventArgs)
Not JITTED yet. Use !bpmd -md 00766db8 to break on run.
And if we know the name of the method but not the module, we can still get the method descriptor and jitted address like this:
0:004> !Name2EE * WindowsApplication1.Form1.InitializeComponent
Module: 790c2000 (mscorlib.dll)
--------------------------------------
...
--------------------------------------
Module: 00762c3c (WindowsApplication1.exe)
Token: 0x06000021
MethodDesc: 00766d60
Name: WindowsApplication1.Form1.InitializeComponent()
JITTED Code Address: 00850a08
--------------------------------------
...
Like a process, an Application Domain or AppDomain is both a container and a boundary. The .NET runtime uses an AppDomain as a container for code and data and to isolate code inside of a secure boundary.
An AppDomain belongs to only a single process, but single process can hold multiple AppDomains: typically a system ___domain (tracks all domains), a shared ___domain (contains code which is shared between all the other app domains), and at least one other app ___domain (the main app ___domain of the app).
In ASP.NET, w3wp.exe will hold system and shared domains, and also a default ___domain and one app ___domain per web application (virtual directory marked as application):
0:000> !dumpdomain
--------------------------------------
System Domain: 7a38bb38
...
--------------------------------------
Shared Domain: 7a38c110
…
--------------------------------------
Domain 1: 001a8d58
…
Name: DefaultDomain
…
--------------------------------------
Domain 2: 001caff8
…
Name: /LM/w3svc/1/ROOT/DebuggingWorkshop-1-128030638920977997
…
Next post: MANAGED DEBUGGING with WINDBG. Setting a Breakpoint. Part 2.
Index: MANAGED DEBUGGING with WINDBG. Introduction and Index.
Regards,
Alex (Alejandro Campos Magencio)
Comments
- Anonymous
June 15, 2012
Thanks for this tutorial, excellent