The procedure was intended to introduce WINDBG using SOS to debug the CLR program in accordance with the sorting of commands on SOS's Help file, but it was not intuitive enough. Instead of the actual case of my analysis of the CLR, step by step introduces the function, which is a bit messy, but more intuitive and easy to start with:P
The first two articles introduce the basic concepts of WINDBG debugging Configuration and threading, which will analyze the process of JIT-compiled object methods and step-by-step how to debug CLR programs using WINDBG.
Exploring the world of the CLR with WinDbg [1]-Installation and environment configuration
Exploring the CLR World with WinDbg [2]-Threads
First write a simple example of the program Demo.cs and compiled to Demo.exe, using the configured WINDBG open:
The following are references:
Using System;
Namespace Flier
{
Class EntryPoint
{
public void M1 ()
{
System.Console.Write ("entrypoint.m1 ()");
}
public void m2 ()
{
System.Console.Write ("entrypoint.m2 ()");
}
public static void Main ()
{
EntryPoint EP = new EntryPoint ();
EP.M1 ();
EP.M2 ();
}
}
}
WINDBG will break execution after loading the demo.exe. The. Load SOS command can be used to load the sos.dll command extension, use the. Chain to verify the success of the load, and then load the Demo.exe debug symbol file with the LD Demo command to verify that the load was successful with the LM command.
Then use LD kernel32 to load Kernel32 Debug symbol file and BP kernel32! Loadlibraryexw the "Du poi (esp+4)" command adds a breakpoint to the function entry that loads the DLL. The next step is the G instruction, until the Mscorwks.dll is loaded. This mscorwks.dll is a virtual machine implementation code similar to the Jvm.dll in the JVM, and most of the features we want to know are in it. Detailed explanation can refer to my previous article ". Analysis of CLR program loading principle under NET Platform
After Mscorwks.dll is loaded with the LD mscorwks command to load its debug symbol library, we can formally start our exploration work:D
The WINDBG commands currently in use are as follows
The following are references:
. load SOS//Load SOS Debugging Extension module, you can use the. Chain Command Verification
LD demo//load Demo.exe Debug symbol library, use LM command to verify
LD KERNEL32//load Kernel32.exe Debug Symbol Library
BP kernel32! Loadlibraryexw "Du poi (esp+4)"//Set Breakpoints Monitor when Mscorwks.dll is loaded
G//execute until Mscorwks.dll is loaded
BD 0//Clear the breakpoint set earlier and start processing the Mscorwks.dll
LD mscorwks//load Mscorwks.dll Debug Symbol Library
Don Box is in the. NET Essence Theory Volume 1th: The Common Language runtime's chapter sixth describes the internal implementation process of the method invocation. It mentions that the method table is saved before the JIT by the call mscorwks.dll! The Prestubworker call is JIT-compiled and invoked by the target IL code until the first time it is used. So our first step is to set a breakpoint on this function (BP mscorwks! Prestubworker), and see how the system calls this function.
The following are references:
0:000> BP mscorwks! Prestubworker
0:000> g
modload:70ad0000 70bb6000 E:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.100.0_ X-ww_8417450b\comctl32.dll
modload:79780000 79980000 E:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll
modload:79980000 79ca6000 e:\windows\assembly\nativeimages1_v1.1.4322\mscorlib\1.0.5000.0__b77a5c561934e089_ Ed6bc96c\mscorlib.dll
modload:79510000 79523000 E:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorsn.dll
Breakpoint 1 Hit
eax=0012f7c0 ebx=00148c60 ecx=04aa112c edx=00000004 esi=0012f784 edi=0012f9a8
EIP=791D6A4A esp=0012f764 ebp=0012f79c iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000
mscorwks! Prestubworker:
791D6A4A Push EBP
A breakpoint is activated to represent a function being invoked. We first use K to see the context when the function is invoked.
The following are references:
0:000> K
ChildEBP RetAddr
0012f760 0014930e mscorwks! Prestubworker
Warning:frame IP not in any known module. Following frames May is wrong.
0012f79c 791da434 0x14930e
0012F8B4 791dd2ec mscorwks! Methoddesc::calldescr+0x1b6
0012f96c 79240405 mscorwks! Methoddesc::call+0xc5
0012fa18 79240520 mscorwks! appdomain::initializedomaincontext+0x10f
0012fa7c 7923d744 mscorwks! systemdomain::initializedefaultdomain+0x11c
0012fd60 791c6e73 mscorwks! systemdomain::executemainmethod+0x120
0012ffa0 791C6EF3 mscorwks! Executeexe+0x1c0
0012ffb0 7880a53e mscorwks!_corexemain+0x59
0012FFC0 77e1f38c mscoree!_corexemain+0x30 [f:\dd\ndp\clr\src\dlls\shim\shim.cpp @ 5426]
0012fff0 00000000 kernel32! baseprocessstart+0x23
Here you can see the steps taken from the Mscoree!_corexemain, and the warning indicates that the stack frame is not in any of the known modules. This is normal because the stack frame actually points to code generated by the JIT dynamically. The mscorwks! we're watching. The Prestubworker function is simply an entry stub to a function in the method table, and other ways of invoking JIT-complete code execution are also invoked at startup.
Next, look at the call stack of the CLR with the!clrstack command of SOS, which appears as follows:
The following are references:
0:000>!clrstack
Succeeded
Loaded Son of Strike data table version 5 from "E:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll"
Thread 0
ESP EIP
0012f784 791d6a4a [Frame:prestubmethodframe] [DEFAULT] [hasthis] Void System.AppDomain.SetupDomain (valueclass system.loaderoptimization,string,string)
0012f9a8 791d6a4a [Frame:gcframe]
0012fad0 791d6a4a [Frame:debuggerclassinitmarkframe]
0012fa94 791d6a4a [Frame:gcframe]
If you need more detail, you can use the-p,-L, or-R parameters to display parameters, local variables, and registers separately, and of course the first two need to debug the symbol library support.
So all the way G;!clrstack carry on until flier. The ENTRYPOINT.M1 function needs to be processed:
The information includes the object's type name and the address (eeclass) of the type information, as well as the object size (size) and Token (MdToken), and the Method table (methodtable) is the target of the profiling method call. We can use the!dumpclass command to further view the object's type information:
The following are references:
0:000>!dumpclass 0x6c632e8
Class Name:flier. EntryPoint
MDTOKEN:02000002 ()
Parent Class:79b7c3c8
classloader:00153850
Method table:009750a8
Vtable slots:4
Total Method Slots:8
Class attributes:100000:
flags:1000003
numinstancefields:0
numstaticfields:0
threadstaticoffset:0
threadstaticssize:0
contextstaticoffset:0
contextstaticssize:0
You can see that there is a lot of conformity between the information and the object information, as Don Box says, an object reference points to a type EEClass instance, and the method table is all of the type and its objects are common. We can use the!DUMPMT command to further view the information of the method table,-MD parameters that require viewing each method description (METHODDESC):
You can see that there are 8 table entries in the method table, where the top 4 are already bound to static functions that are precompiled using NGen
The following are references:
0:000> u 79b7c4eb
MSCORLIB_79980000+0X1FC4EB:
79b7c4eb E8909cfeff call mscorlib_79980000+0x1e6180 (79b66180)
79b7c4f0 0000 Add [Eax],al
79b7c4f2 0080d86206c0 Add [eax+0xc00662d8],al
79b7c4f8 Modified ES
79b7c4f9 00FC Add AH,BH
79B7C4FB E8809cfeff call mscorlib_79980000+0x1e6180 (79b66180)
79b7c500 Modified Pop ES
79b7c501 0010 Add [eax],dl
The latter four are then used as a virtual method to be overridden in the method table, which is why Vtable slots = 4 While viewing type information is slots = 8.
For each item of the method table, you can use! DUMPMD command to view detailed descriptions, such as
The Il RVA indicates that the IL code for this method is relative to the virtual address (Il RVA), which means that the method is not yet JIT and still exists as an IL code. For methods that have completed the JIT, the virtual address (method VA) of its JIT function body code is displayed:
The WINDBG commands used in this phase are as follows:
The following are references:
!dumpobj 04aa1a90//View details of the object
!dumpclass 0x6c632e8//view type details
!DUMPMT-MD 0x09750a8//View details of the method table
!DUMPMD 0x00975070//View details of method descriptions for method table entries
U 0x79b7c4eb//Disassembly instructions for the specified address
Let's disassemble it! Several methods listed in the DUMPMT command will find that, as Don Box says, the JIT code points to a jmp instruction and jumps directly to the compiled method body, such as:
The following are references:
0:000> u 0097509b
0097509b e908b04106 jmp 06d900a8
A function that is not JIT, then points to a call instruction, invokes a Prolog code, and indirectly invokes the mscorwks! The Prestubworker function completes the actual JIT work, such as:
The following are references:
0:000> u 0x0097506b
0097506b E878427DFF Call 001492e8
0:000> u 0x0097507b
0097507b E868427DFF Call 001492e8
This prolog code is very simple, responsible for constructing mscorwks! Call stack required by Prestubworker
The following are references:
0:000> u 0x001492e8
001492e8 push edx
001492e9 68f0301b79 Push 0x791b30f0
001492EE Push EBP
001492EF push EBX
001492F0 push ESI
001492F1 Push EDI
001492F2 8d742410 Lea esi,[esp+0x10]
001492f6 Wuyi ECX
001492F7 push edx
001492f8 648b1d2c0e0000 mov ebx,fs:[00000e2c]
001492FF 8B7B08 mov edi,[ebx+0x8]
00149302 897E04 mov [esi+0x4],edi
00149305 897308 mov [ebx+0x8],esi
00149308 push ESI
00149309 e83cd70879 Call mscorwks! Prestubworker (791D6A4A)
0014930e 897B08 mov [ebx+0x8],edi
00149311 894604 mov [esi+0x4],eax
00149314 5a Pop EdX
00149315 pop ECX
00149316 5f Pop EDI
00149317 5e pop ESI
00149318 5b pop ebx
00149319 5d Pop Ebp
0014931a 83c404 Add esp,0x4
0014931d 8f0424 pop [ESP]
00149320 c3 ret
This prolog code is dynamically generated by a similar generateprestub function (vm\i386\cgenx86.cpp:1829) in rotor, which completes the encapsulation of the Prestubworker function call. The Prestubworker function invokes the JIT to complete the actual function compilation and changes the entry of the method table to point to the jmp instruction of the compiled function body. For specific procedures please refer to Don Box in the. NET essence of the 1th volume: the Common language runtime in the sixth chapter of the introduction, here is no longer wordy. Later have the opportunity to write an article detailed analysis of the JIT workflow.
In the JIT processing flier. ENTRYPOINT.M1, with the G command to perform, and then back to analyze the entry of the M1 function, it will be found as described above, the call to invoke the JIT process has become a direct call to the Native function body JMP instructions. :D
In this section, we describe the process of using WINDBG to track debugging CLR programs, and the SOS command that analyzes stack, object, and class information, and hopefully you can start exploring the inner world of the CLR's journey. :P
Jason Zander in an article in his BLog, SOS debugging with the CLR (Part 1), which also details some of the methods used to debug CLR programs using WINDBG and SOS, which is worth looking at.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.