1024programmer Asp.Net Net Advanced Debugging No. 10: Debugging of lightweight code generation

Net Advanced Debugging No. 10: Debugging of lightweight code generation

Net Advanced Debugging No. 10: Debugging of lightweight code generation

1. Introduction
Today is the tenth article of “Net Advanced Debugging”. Speaking of advanced debugging, there is still a lot of debugging content and many skills. However, if you want to be a qualified senior debugger, you also need to master how to debug dynamically generated IL code. The advanced debugging technique we will explore today is how to debug IL code dynamically generated through Emit. Someone may ask, aren’t we writing C# code, or VB.Net code? Why do we need to dynamically generate IL code? Isn’t this work done by the compiler? Of course, this is generally the case, but when we write some high-performance frameworks, it is also common to write in IL code. Since you can also directly use IL to write code, debugging it is also indispensable. Although there are few debugging opportunities, if you have this ability, you will not panic when you encounter such a problem. As the saying goes: There is no pressure when you have more skills. body. 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. All over, its meaning appears by itself.
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. Dynamic code debugging
  Although there are not many opportunities for dynamic code debugging , but it is still necessary to master the skills of dynamic code debugging. As the saying goes, many skills do not overwhelm the body. When we encounter problems caused by writing code like this, we can also stay calm.
Today we will discuss three debugging techniques.

 2. Three debugging strategies

 2.1. Capture JIT’s CompileMethod method.
      The compilation process of C# code is divided into two stages. The first stage is the compiler stage. At this stage, the compiler compiles the C# source code we wrote into IL code. The second stage is the compiler stage. stage, when running, JIT compiles the IL code into machine code, and our program runs. Now it is the dynamically generated IL code. There is no first stage, it is directly the second JIT compilation stage. We can try to set a breakpoint in a certain method of JIT to intercept and get the method descriptor, which is MD. , with MD, we can use the bp md command to set a breakpoint for this method, so that we can debug the dynamically generated code.

  2.2. Obtain the function pointer of the delegate from the code (my test did not implement it).
This method is relatively simple, but it requires adding a line of code to the method, which is somewhat destructive. . Code: Marshal.GetFunctionPointerForDelegate(delegate instance).ToInt64().

  2.3. Inject Debugger.Break() into dynamic code.
                                      will be used to allow the program to interrupt the debugger. If we have complete control over this dynamic code, we can inject this method: Debugger.Break(), implements int 3 interrupt, and then obtains the desired data. The code is as follows: IL.Emit(OpCodes.Call,typeof(Debugger).GetMethod(“Break”)).

 3. Assembly
  3.1. Assembly crash
What does assembly leakage mean? That is, the memory of the program has skyrocketed, resulting in a large number of assembly assemblies.

3. Debugging Process
Without further ado, this section is about the specific debugging operations. process,It can also be said that seeing is believing. Before I start, 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 testing or debugging. There must be 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
                                                                                                                                            ccoutes              
   1.1、Example_10_1_1

 1 namespace Example_10_1_1
  2 {
  3 internal  span> class Program
  4  {
  5 private  span> delegate int  AddDelegate(int a, int b);
  6 static  span> void Main(string[] args)
  7  {
  8 var  span> dynamicAdd = new DynamicMethod("  Add"  span>, typeof(int), new Type[] { typeof(int), typeof(int) });
  9 var  span> il = dynamicAdd.GetILGenerator();
 10  il.Emit  (OpCodes.Ldarg_0);
 11  il.Emit  (OpCodes.Ldarg_1);
 12  il.Emit  (OpCodes.Add);
 13  il.Emit  (OpCodes.Ret);
 14
 15 var addDelegate =  (AddDelegate)dynamicAdd.CreateDelegate(typeof  (AddDelegate));
 16 Console.WriteLine(addDelegate(10, 20));
 17  }
 18  }
 19 }

View Code

   1.2、Example_10_1_2

 1 namespace Example_10_1_2
  2 {
  3 internal  span> class Program
  4  {
  5 private  span> delegate int  AddDelegate(int a, int b);
  6 static  span> void Main(string[] args)
  7  {
  8 var  span> dynamicAdd = new DynamicMethod("  Add"  span>, typeof(int), new Type[] { typeof(int), typeof(int) });
  9 var  span> il = dynamicAdd.GetILGenerator();
 10  il.Emit  (OpCodes.Ldarg_0);
 11  il.Emit  (OpCodes.Ldarg_1);
 12  il.Emit  (OpCodes.Add);
 13  il.Emit  (OpCodes.Ret);
 14
 15 var addDelegate =  (AddDelegate)dynamicAdd.CreateDelegate(typeof  (AddDelegate));
 16
 17 Console.WriteLine("  span>Function Pointer:0x{0:x16}", Marshal.GetFunctionPointerForDelegate(addDelegate).ToInt64());
 18
 19  Debugger.Break();
 20
 21 Console.WriteLine(addDelegate(10  , 20))  ;
 22  }
 23  }
 24 }

View Code

   1.3、Example_10_1_3

 1 0x6b
 26 14 010ff354 6f18b11b  clr!MethodDescCallSite::CallTargetWorker+0x16a
 27 15 010ff478 6f18b7fa  clr!RunMain+0x1b3
 28 16 010ff6e4 6f18b727  clr!Assembly::ExecuteMainMethod+0xf7
 29 17 010ffbc8 6f18b8a8  clr!SystemDomain::ExecuteMainMethod+0x5ef
 30 18 010ffc20 6f18b9ce  clr!ExecuteEXE+0x4c
 31 19 010ffc60 6f187305  clr!_CorExeMainInternal+0xdc
 32 1a 010ffc9c 721bfa84 clr!_CorExeMain+0x4d  
 33 1b 010ffcd4 7224e81e mscoreei!_CorExeMain+0xd6  
 34 1c 010ffce4 72254338  MSCOREE!ShellShim__CorExeMain+0x9e
 35 1d 010ffcfc 765ff989 MSCOREE!_CorExeMain_Exported+0x8  
 36 1e 010ffcfc 77b27084 KERNEL32!BaseThreadInitThunk+0x19  
 37 1f 010ffd58 77b27054 ntdll!__RtlUserThreadStart+0x2f  
 38 20 010ffd68 00000000 ntdll!_RtlUserThreadStart+0x1b  

Or we can use the [!clrstack] command to check the call stack. This command can see it more clearly.

 1 0:000> !clrstack
  2 OS Thread Id: 0x3534 (0  )
  3 Child SP IP  Call Site
  4 010fee44 6f166b49 [  HelperMethodFrame_PROTECTOBJ: 010fee44] System.Reflection.Emit.AssemblyBuilder.nCreateDynamicAssembly(System.AppDomain, System.Reflection.AssemblyName, System.Security.Policy.Evidence, System.Threading.StackCrawlMark ByRef, System.Security.PermissionSet, System.Security.PermissionSet  , System.Security.PermissionSet, Byte[], Byte[], System.Reflection.Emit.AssemblyBuilderAccess, System.Reflection.Emit.DynamicAssemblyFlags, System.Security.SecurityContextSource)
  5 010fef20 6dfef391 System.Reflection.Emit.AssemblyBuilder..ctor(System.AppDomain, System.Reflection.AssemblyName  , System.Reflection.Emit.AssemblyBuilderAccess, System.String, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.Security.PermissionSet, System.Threading.StackCrawlMark ByRef, System.Collections.  Generic.IEnumerable`1, System.Security.SecurityContextSource) [f:\dd\  ndp\clr\src\BCL\system\reflection\emit\assemblybuilder.cs @ 424]
  6 010fefa8 6dfef261 System.Reflection.Emit.AssemblyBuilder.InternalDefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.  Emit.AssemblyBuilderAccess, System.String, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.Security.PermissionSet, System.Threading.StackCrawlMark ByRef, System.Collections.Generic.IEnumerable`1, System.Security.SecurityContextSource) [f:\dd\ndp\clr\src  \BCL\system\reflection\emit\assemblybuilder.cs @ 569]
  7 010feffc 6e016558 System.AppDomain.InternalDefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess,  System.String, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.Security.PermissionSet, System.Threading.StackCrawlMark ByRef, System.Collections.Generic.IEnumerable`1, System.Security.SecurityContextSource) [f:\dd\ndp\clr\src\BCL\system  \appdomain.cs @ 1515]
  8 010ff028 6e016527 System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)  [f:\dd\ndp\clr\src\BCL\system\appdomain.cs @ 1221]
  9 010ff038 6bd100bd System  .Xml.Serialization.CodeGenerator.CreateAssemblyBuilder(System.AppDomain, System.String)
 10 010ff04c 6bd0fa1b System  .Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(System.Xml.Serialization.XmlMapping[], System.Type[], System.String, System.Security.Policy.Evidence)
 11 010ff0ec 6bd0f696 System  .Xml.Serialization.TempAssembly..ctor(System.Xml.Serialization.XmlMapping[], System.Type[], System.String, System.String, System.Security.Policy.Evidence)
 12 010ff128 6c09db2a System  .Xml.Serialization.XmlSerializer.GenerateTempAssembly(System.Xml.Serialization.XmlMapping, System.Type, System.String, System.String, System.Security.Policy.Evidence)
 13 010ff14c 6c09da72 System.Xml.Serialization.XmlSerializer..ctor(System.Type, System.Xml.Serialization.  XmlAttributeOverrides, System.Type[], System.Xml.Serialization.XmlRootAttribute, System.String, System.String, System.Security.Policy.Evidence)
 14 010ff184 6c09d8e7 System.Xml.Serialization.XmlSerializer..ctor(System.Type, System.Xml.Serialization.  XmlRootAttribute)
 15 010ff198 017710aa Example_10_1_4.Program.GetCustomer(Int32, System.String, System.String) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 27]
 16 010ff1f4 01770ffc Example_10_1_4.Program+c__DisplayClass0_0.b__0(Int32) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 18]
 17 010ff208 01770f88 System.Linq.Enumerable+WhereSelectEnumerableIterator`2[[System.Int32, mscorlib],[System.__Canon, mscorlib]].MoveNext  ()
 18 010ff218 6dfaaa67 System.Collections.Generic.List`1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1) [f:\dd\ndp\clr\src\BCL\system\collections\generic\list.cs @ 99]
 19 010ff24c 6c77c5de System.Linq.Enumerable.ToList[[System.__Canon, mscorlib]](System.Collections  .Generic.IEnumerable`1)
 20 010ff260 017708f2 Example_10_1_4.Program.Main(System.String[]) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 17]
 21 010ff3f8 6efdf036 [GCFrame: 010ff3f8] 

We finally found the problem. The solution has already been written in the code.

IV. Summary
Finally I have finished writing. The writing process is tiring and happy at the same time. The learning process is really not that easy. Fortunately, I like this industry better, otherwise I don’t know if I can persist. Let’s talk about the old saying again. The first time I read the book “Advanced Debugging”, I was really confused. The second time it was a little better. If you don’t learn, you won’t know. Once you learn, you will be shocked. You will find that you lack a lot. 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.rgba(128, 0, 128, 1)”>1, System.Security.SecurityContextSource) [f:\dd\ndp\clr\src\BCL\system\reflection \emit\assemblybuilder.cs @ 569 ]
7 010feffc 6e016558 System.AppDomain.InternalDefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess, System.String, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.Security.PermissionSet, System.Threading.StackCrawlMark ByRef, System.Collections.Generic.IEnumerable`1, System.Security.SecurityContextSource) [f:\dd\ndp\clr\src\BCL\system \appdomain.cs @ 1515]
8 010ff028 6e016527 System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess) [f:\dd\ndp\clr\src\BCL\system\appdomain.cs @ 1221]
9 010ff038 6bd100bd System .Xml.Serialization.CodeGenerator.CreateAssemblyBuilder(System.AppDomain, System.String)
10 010ff04c 6bd0fa1b System .Xml.Serialization.TempAssembly.GenerateRefEmitAssembly(System.Xml.Serialization.XmlMapping[], System.Type[], System.String, System.Security.Policy.Evidence)
11 010ff0ec 6bd0f696 System .Xml.Serialization.TempAssembly..ctor(System.Xml.Serialization.XmlMapping[], System.Type[], System.String, System.String, System.Security.Policy.Evidence)
12 010ff128 6c09db2a System .Xml.Serialization.XmlSerializer.GenerateTempAssembly(System.Xml.Serialization.XmlMapping, System.Type, System.String, System.String, System.Security.Policy.Evidence)
13 010ff14c 6c09da72 System.Xml.Serialization.XmlSerializer..ctor(System.Type, System.Xml.Serialization. XmlAttributeOverrides, System.Type[], System.Xml.Serialization.XmlRootAttribute, System.String, System.String, System.Security.Policy.Evidence)
14 010ff184 6c09d8e7 System.Xml.Serialization.XmlSerializer..ctor(System.Type, System.Xml.Serialization. XmlRootAttribute)
15 010ff198 017710aa Example_10_1_4.Program.GetCustomer(Int32, System.String, System.String) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 27]
16 010ff1f4 01770ffc Example_10_1_4.Program+c__DisplayClass0_0.b__0(Int32) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 18]
17 010ff208 01770f88 System.Linq.Enumerable+WhereSelectEnumerableIterator`2[[System.Int32, mscorlib],[System.__Canon, mscorlib]].MoveNext ()
18 010ff218 6dfaaa67 System.Collections.Generic.List`1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1) [f:\dd\ndp\clr\src\BCL\system\collections\generic\list.cs @ 99]
19 010ff24c 6c77c5de System.Linq.Enumerable.ToList[[System.__Canon, mscorlib]](System.Collections .Generic.IEnumerable`1)
20 010ff260 017708f2 Example_10_1_4.Program.Main(System.String[]) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test\Example_10_1_4\Program.cs @ 17]
21 010ff3f8 6efdf036 [GCFrame: 010ff3f8]

We finally found the problem. The solution has already been written in the code.

IV. Summary
Finally I have finished writing. The writing process is tiring and happy at the same time. The learning process is really not that easy. Fortunately, I like this industry better, otherwise I don’t know if I can persist. Let’s talk about the old saying again. The first time I read the book “Advanced Debugging”, I was really confused. The second time it was a little better. If you don’t learn, you won’t know. Once you learn, you will be shocked. You will find that you lack a lot. 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.gram.Main(System.String[]) [E:\Visual Studio 2022\Source\Projects\AdvancedDebug.NetFramework.Test \Example_10_1_4\Program.cs @ 17 ]
21 010ff3f8 6efdf036 [GCFrame: 010ff3f8]

We finally found the problem. The solution has already been written in the code.

IV. Summary
Finally I have finished writing. The writing process is tiring and happy at the same time. The learning process is really not that easy. Fortunately, I like this industry better, otherwise I don’t know if I can persist. Let’s talk about the old saying again. The first time I read the book “Advanced Debugging”, I was really confused. The second time it was a little better. If you don’t learn, you won’t know. Once you learn, you will be shocked. You will find that you lack a lot. 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.

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/net-advanced-debugging-no-10-debugging-of-lightweight-code-generation/

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索