Introducing Rotor: _CorExeMain2

Link. February 2, 2003. Comments [0]. Posted in: .NET
Today, I started looking at the runtime startup code. This journey begins in _CorExeMain2(), implemented in sscli\clr\src\vm\ceemain.cpp, which is declared like this:
__int32 STDMETHODCALLTYPE _CorExeMain2( // Executable exit code.
    PBYTE   pUnmappedPE,                // -> memory mapped code
    DWORD   cUnmappedPE,                // Size of memory mapped code
    LPWSTR  pImageNameIn,               // -> Executable Name
    LPWSTR  pLoadersFileName,           // -> Loaders Name
    LPWSTR  pCmdLine)                   // -> Command Line

The names of the arguments the function takes should be self-explanatory, specially if you look at the code in clix.exe. The function itself is fairly short, consisting mostly of error handling code. In a nutshell, it does this:

  1. Verify the strong name signature of the assembly, if there is one present, via the StrongNameSignatureVerification() function (implemented in sscli\clr\src\dlls\mscorsn\strongname.cpp
  2. Handle all command line arguments, and store them for later use
  3. Initialize the CLR Execution Engine
  4. Execute the actual Main() method of the module loaded
  5. Once this ends, cleanly shutdown the Execution Engine

There isn't much more to say about this, but I can't help but nitpick and poke around the things that are probably far less relevant than anything you might read elsewhere :) For example, I had no idea the Runtime could take command line arguments itself.... just try writing a simple application like this:

using System;
class Test
{
   public static void Main(String[] args)
   {
      Console.WriteLine(args.Length);
   }
}

Now, try running it with a command line like "App.exe -COR somethinghere"... and low-and-behold, it prints 0! The magic of this is inside the ParseCor() method of the CorCommandLine class, implemented in sscli\clr\src\vm\clsload.cpp. I must admit, though, that I was unable to actually find anywhere in the code they where used.

OK, now going back to the serious stuff. The EE initialization is done through the CoInitializeEE(), which handles some locking stuff and then calls the TryEEStartup() function, which itself calls the real potato: EEStartup().

At a glance, EEStartup does, among other things, initialize the Stack Probes and the event store, load configuration data (not the application .config file, though, not yet.), initialize the thread manager, remoting services and context system, the JIT, the GC, SyncBlock cache, the P/Invoke services, security subsystem, and, of course, setup the default domain. The configuration loading code is done by the EEConfig class, implemented in sscli\clr\src\vm\eeconfig.cpp

While this function is not really complicated per se, it sets up the entire VM execution environment. Thus, really understanding everything that's going on will take some more time. This is where the good stuff begins!



Comments are closed.

Syndicate

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Ads


Categories

Statistics

Total Posts: 1050
This Year: 1
This Month: 1
This Week: 0
Comments: 825

Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.2.8279.16125

Sign In