Net advanced debugging part 5: How to set breakpoints on managed functions
1. Introduction
Today is the fifth article of “Net Advanced Debugging”. Today’s article begins by introducing how to set breakpoints in managed and unmanaged methods. If we want to debug a program, we must master some debugging commands. We have already talked about dynamic debugging commands in the previous article. Commands alone are not enough. To make these debugging commands useful, breakpoints must be set on the method, and then the debugging commands can be used to complete our debugging tasks. Of course, when you watch a video or read a book for the first time, you will be very confused and don’t know how to operate it. As the old saying goes, if it doesn’t work once, then try it again. If it doesn’t work, then try it again. As the saying goes, you can read a thousand books. This is the third time for me to do it.
If there is no explanation, the test environment for all codes is Net Framewok 4.8. However, sometimes in order to view the source code, you may need to use Net Core projects. I will explain it in the project chapter. Okay, without further ado, let’s start our debugging work today.
I need to explain the debugging environment in case everyone is unclear. I have listed the specific circumstances.
Operating system: Windows Professional 10
Debugging tool: Windbg Preview (you can go to Microsoft Store to download)
Development tool: Visual Studio 2022
Net version: Net Framework 4.8
CoreCLR source code: source code Download
2. Basic knowledge
1. Breakpoints under unmanaged functions
In fact, it is very convenient to set breakpoints on unmanaged functions, because the C/C++ function becomes [machine code] after compilation, and the function name enters the [symbol table]. For example, we can Conveniently set breakpoints in notepad’s SaveFile function.
The steps are as follows:
a. Open notepad.
b. Use x notepad!SaveFile to set a breakpoint.
c. Save the file on notepad and the breakpoint will be triggered.
2. Breakpoint under managed function
2.1. Introduction
It is difficult to set breakpoints in managed functions because the machine code of the method you want to set a breakpoint may not have been generated in the memory. That is to say, JIT has never compiled this method, so it is more troublesome to set breakpoints on code that has not yet been generated. Although it is more troublesome, it does not mean that it cannot be implemented. We still have three methods to set breakpoints on managed functions.
2.2. Three ways to set breakpoints under managed functions
1 ), breakpoints above and below the compiled function
This is the simplest way. Since the method has been compiled, machine code must have been generated, so breakpoints above and below the compiled function. It’s much easier, and it’s the same as unmanaged.
2), Breakpoints above and below uncompiled functions
through up and down breakpoints on uncompiled functions
a. Use !bpmd assembly.exe (module contains suffix name) namespace.ClassName.MethodName
b , use sosex extended mbm breakpoint (can only be used under Net framework, Net Core is not supported).
3), set breakpoints on generic methods
forward forward in in ininging>>3). Set breakpoints on generic methods
After finding the name of the type type and the name of the method, we can set a breakpoint. There are two ways to find the names of generic types and methods. The first is through commands, and the second is that we can use ILSpy to find them.
3. Debugging Process
Without further ado, this section is specific. The process of debugging operations can also be said to be a process of seeing is believing. Before starting, I still want to say a few words. This section is divided into two parts. The first part is the source code part of the test. Without the code, of course there is no way to talk about it. Tested on, debugging must have a carrier. The second part is to verify the knowledge we have learned based on specific code, which is based on seeing is believing.
1. Test source code
1.1. Example_5_1_1
1 namespace Example_5_1_1 2 { 3 internal span> class Program 4 { 5 static span> void Main(string[] args) 6 { 7 var span> sum = Sum(10, 20); 8 9 Debugger.Break(); 10 11 sum = Sum(100, 200); 12 13 Console.WriteLine($"sum={sum} "); 14 } 15 16 private static int Sum(int a, int b) 17 { 18 var span> sum = a + b; 19 20 return sum; 21 } 22 } 23 }
View Code
1.2、Example_5_1_2
1 namespace Example_5_1_2 2 { 3 internal span> class Program 4 { 5 static span> void Main(string[] args) 6 { 7 Console.WriteLine("Please see: Sum method in uncompiled form"); 8 Debugger.Break (); 9 10 var sum = Sum(10,20); 11 Console.WriteLine("Please view: Sum method in compiled form"); 12 Debugger.Break (); 13 14 sum = Sum(100, 200); 15 16 Console.WriteLine($"sum={sum} "); 17 } 18 19 private static int Sum(int a, int b) 20 { 21 var span> sum = a + b; 22 23 return sum; 24 } 25 } 26 }
View Code
1.3、Example_5_1_3
1 namespace Example_5_1_3 2 { 3 internal span> class Program 4 { 5 static span> void Main(string[] args) 6 { 7 Debugger.Break (); 2 EEClass: 01001334 3 Module: 01004044 4 Name: Example_5_1_3.MyList`1 5 mdToken: 02000003 6 File: E:\Visual Studio 2022\Source\Projects\......\Example_5_1_3\bin\Debug\Example_5_1_3.exe 7 BaseSize: 0xc 8 ComponentSize: 0x0 9 Slots in VTable : 6 10 Number of IFaces in IFaceMap: 0 11 -------------------------- ---------- 12 MethodDesc Table 13 Entry MethodDe JIT Name 14 6fbf97b8 6f7fc838 PreJIT System.Object.ToString() 15 6fbf96a0 6f938978 PreJIT System.Object.Equals(System.Object) 16 6fc021f0 6f938998 PreJIT System.Object.GetHashCode() 17 6fbb4f2c 6f9389a0 PreJIT System.Object.Finalize() 18 02840458 span> 01004dd4 NONE Example_5_1_3.MyList`1..ctor() 19 02840450 span> 01004dcc NONE Example_5_1_3.MyList`1.Add(!0)
The red mark is the Add method we are looking for. With the address of the method, we can use the [bpmd] command to set a breakpoint for it.
1 0:000> !bpmd Example_5_1_3 Example_5_1_3.MyList`1.Add 2 Found 1 methods in module 01004044... 3 MethodDesc = 01004dcc 4 Adding pending breakpoints...
After the breakpoint is successfully set, we use the [g] command to continue running the program and pause at the breakpoint.
1 0:000> g 2 (3ab4. 2920): CLR notification exception - code e0444143 (first chance) 3 JITTED Example_5_1_3!Example_5_1_3.MyList`1[[System.Int32, mscorlib]].Add(Int32) 4 Setting breakpoint: bp 02840942 [Example_5_1_3.MyList`1[[System.Int32, mscorlib]].Add(Int32)] 5 Breakpoint: JIT notification received for method Example_5_1_3.MyList`1[[System.Int32, mscorlib]].Add(Int32) inAppDomain 00a2da30. 6 Breakpoint 0 hit 7 eax=02840928 ebx=007bee20 ecx=029f26b0 edx=0000000a esi=00000000 edi=007bed90 8 eip=02840942 esp=007bed58 ebp=007bed60 iopl=0 nv up ei pl zr na pe nc 9 cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 10 Example_5_1_3!COM+_Entry_Point (Example_5_1_3+0x2220942): 11 02840942 span> 90 nop
The breakpoint effect is as shown in the figure:
>
b. We can use ILSpy to find the names of generic types and method names.
The effect is as shown in the figure:
<IMG SRC = "https://img2023.cnblogs.com/blog/1048776/202311/1048776-202313131313133897.png" all = "" "" "" "" "" "" "" "" " "
The above is the name of the type. I continue to look for the name of the method, which is also very simple.
The effect is as shown below:
With this information, we can use Windbg to set breakpoints for the program. The operation process is the same as a, so I won’t go into details.
IV. Summary
It’s finally finished. Why do you say it’s finally, because it took more than a day to write this article. Completed. It takes a long time to write an article, record the operation process, and draw illustrations. Today we introduce how to set breakpoints on methods. With breakpoints, we can use the dynamic debugging commands mentioned in the previous article, and we can complete debugging tasks more easily. It is still necessary to master these debugging skills. Okay, let’s not talk anymore. Don’t forget your original intention and continue to work hard. I hope God will not let down those who work hard.
All countries in the world can be equalized; honors and positions can be dismissed; swordsmanship can be practiced; moderation is impossible.1[[System.Int32, mscorlib]].Add(Int32) inAppDomain 00a2da30.
6 Breakpoint 0 hit
7 eax=02840928 ebx=007bee20 ecx=029f26b0 edx=0000000a esi=00000000 edi=007bed90
8 eip=02840942 esp=007bed58 ebp=007bed60 iopl=0 nv up ei pl zr na pe nc
9 cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
10 Example_5_1_3!COM+_Entry_Point (Example_5_1_3+0x2220942):
11 02840942 span> 90 nop
The breakpoint effect is as shown in the figure:
>
b. We can use ILSpy to find the names of generic types and method names.
The effect is as shown in the figure:
<IMG SRC = "https://img2023.cnblogs.com/blog/1048776/202311/1048776-202313131313133897.png" all = "" "" "" "" "" "" "" "" " "
The above is the name of the type. I continue to look for the name of the method, which is also very simple.
The effect is as shown below:
With this information, we can use Windbg to set breakpoints for the program. The operation process is the same as a, so I won’t go into details.
IV. Summary
It’s finally finished. Why do you say it’s finally, because it took more than a day to write this article. Completed. It takes a long time to write an article, record the operation process, and draw illustrations. Today we introduce how to set breakpoints on methods. With breakpoints, we can use the dynamic debugging commands mentioned in the previous article, and we can complete debugging tasks more easily. It is still necessary to master these debugging skills. Okay, let’s not talk anymore. Don’t forget your original intention and continue to work hard. I hope God will not let down those who work hard.
All countries in the world can be equalized; honors and positions can be dismissed; swordsmanship can be practiced; moderation is impossible.