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