JIT Just–in-Time Compiler Debugging

The standard PE header comes at the beginning of the file. Inside the file is the CLR header, followed by the data required to load the code into its process space—referred to as metadata. It describes to the execution engine how the module should be loaded, what additional files it needs, how to load those additional files, and how to interact with COM and the .NET runtime. Metadata also describes the methods, interfaces, and classes contained in the module or assembly. The information the metadata provides allows the JIT compiler to compile and run the module. The metadata section exposes much of your applications internals and eases the transition from disassembled IL to useful code.

3.3 JIT Just–in-Time Compiler Debugging

The .NET Runtime ships with a Just-In-Time JIT or JITter compiler, which will convert the MSIL code in to the native code CPU Specific executable code. So whatever code we write will be complied in to MSIL format and the JIT takes over when you run it. The .NET runtimeCommon Language Runtime CLR ships three different classes of JITters. The Main JIT compiler converts the MSIL code it to native code with out any optimizations. The JIT compiler takes the MSIL code and optimizes it. So this compiler requires lot of resources like, time to compile, larger memory footprint, etc. The PreJIT is based on the Main JIT and it works like the traditional compilers compiles MSIL to native code during compilation time rather than runtime. This compiler is usually used at the time of installation. No matter whatever language we used to develop the HelloWorld program, it’s a known fact that compiler’s are going to generate a MSIL format, once our code has been converted in to MSIL format, from MSIL format all the code that we write will be converted to native code in the same way whether if it is a VB.NET source or C source. Intermediate Language IL To support our discussion let us examine the IL code of HelloWorld program written using VB.NET and C. To visualize the IL code Microsoft provides a disassembler tool through which you can easily see the IL code To use the tool, choose command prompt and type ILDASM-ILDASM dialog is shown- choose file open dialog and select the assembly make sure you set your path variable to point to the place where your ILDASM is available Figure showing disassembled HelloWorld program The above window showing a tree displays the path of the assembly as the root node, manifest information and namespace information as the child node if you do not specify the namespace for the class then class name will be shown instead of namespace. Figure showing manifest information of helloworld program The manifest information shows the dependent assemblies like mscorlib, Microsoft.VisualBasic and their versions and it self describes the HelloWorld assembly. Since we have a simple program, which does not contain any embedded resource, the manifest does not include any information on those. Figure showing list of information present in the namespace The above figure shows the list of information present within the namespace. In general the namespace contains the list of classes, structures, delegates, enums etc., In this case it shows the HelloWorld class which in turn contains the methods present in the class. It also shows the following information. .class public auto ansi The above figure shows that HelloWorld is derived from System.Object, System.Object is the base class in the .NET framework .ctor : void The above figure shows the IL code of the constructor of HelloWorld Class, you can see that it in turn calls System.Object::.ctor, which is the base class’s constructor Main : void The above figure shows the IL code of the Main function, which is the entry point for that assembly. It also shows the method “System.Console::WriteLine” is called with the string “HelloWorld “ within the Main function Compiler Options If you can recollect the statement we have used to compile the HelloWorld program is vbc HelloWorld.vb for Vb.NET and csc HelloWorld.cs for C , in this we have used the default settings of the compiler. Let us spend sometime in compiling the same code with some important options of the vbc csc compiler. In our program we have referred System.Dll assembly, in real life we would be application-referring lot of assemblies, in those cases the compiler should be intimated about the references. We can achieve this by the option mentioned below reference:file-list - needs to be used to indicate the list of references used by the application, in short it can also be represented as “r”. In our case it will be represented like this statement given below vbc reference:”System.dll” HelloWorld.vb for Vb.NET csc reference:”System.dll” HelloWorld.cs for C.NET The compiler by default will produce a HelloWorld.exe, in case you want to create a module or a library, then you have to specify the target in the compiler. It can be done like this vbc target:library reference:”System.dll” HelloWorld.vb = to generate a library csc target:library reference:”System.dll” HelloWorld.cs = to generate a library Executing the above line of statement in the command prompt will generate a HelloWorld.dll, in the same manner a module can be generated by applying this switch target:module In case if we would like to give a different name to the assembly file then the statement given below can be applied vbc target:exe out:”SampleHelloWorld.exe” reference:”System.dll” HelloWorld.vb csc target:exe out:”SampleHelloWorld.exe” reference:”System.dll” HelloWorld.cs In the above statement the switch out:filename is used to give a different name to the output assembly file. The above compiler statements what we have seen is for simple applications, let us assume we have an application which is a Win32 executable and it has got resources, which could be embedded or linked More on resource file later. An embedded resource could be an image for the splash screen, in those cases the following compiler options will be used target:winexe - used to create a Win32 executable file linkresource:resource files - used to link a resource file to the assembly resource:resource files - used to embed a resource file to the assembly imports:import list - used to include the list of namespaces used by the assembly For other compiler options refer .Net framework SDK documentation. .NET Debugging Debugging is the most important feature of any programming language and Visual Studio .NET IDE provides this feature in an effective manner but you can still do pretty good job with the .NET SDK alone. Application source code goes through two distinct steps before a user can run it. First, the source code is compiled to Microsoft Intermediate Language MSIL code using a .NET compiler. Then, at runtime, the MSIL code is compiled to native code. When we debug a .NET application, this process works in reverse. The debugger first maps the native code to the MSIL code. The MSIL code is then mapped back to the source code using the programmers database PDB file. In order to debug an application, these two mappings must be available to the .NET runtime environment. To accomplish the mapping between the source code and the MSIL, use thedebug:pdbonly compiler switch to create the PDB file Note: When building ASP.NET applications, specify the compilation setting debug=true in the application’s Web.config file. The second mapping between the MSIL code and native code is accomplished by setting the JITTracking attribute in our assembly. By specifying the debug compiler switch, the PDB file is created and the JITTracking attribute is enabled. When using this compiler switch, a debugger can be attached to an application loaded outside of the debugger. Once the required mappings exist, there are several means by which to debug our applications. We can use the integrated debugger within Visual Studio .NET, or, if we prefer, we can use DbgClr, a GUI-based debugger. There is also a command line debugger, CorDBG that is included in the .NET Framework SDK.

3.4 Managed Vs. Unmanaged MethodsTransitions