前面提到在SSCLI环境里运行.NET程序的时候,执行的命令类似java程序的执行过程,即通过clix程序解释执行.net程序。这个过程看起来跟在windows环境下执行.net程序表面上看起来不一样 – Windows环境下的CLR直接执行.net程序文件即可执行,其实内部运作机制是一样的,在后文我会讲解到。

首先我们先来解读下clix的源码,其源码位置位于:clr\src\tools\clix\clix.cpp,入口的main函数在clix.cpp:157行。

刚开始的159 ~ 266行都是执行命令行参数解析以及错误处理的代码,主要分三大块,162 ~ 166行的目的是判断rotor_palrt和sscoree两个dll库文件是否在进程中加载了,rotor_palrt这个库文件在后面解读平台抽象层(PAL)的时候会提到,而sscoree这个库文件的作用跟CLR里面的mscoree.dll的作用是一致的,即用来加载正确的CLR版本。如将要执行的.net程序是在.net 4.0下面编译的,则加载.net 4.0的clr,如果运行的是.net 2.0的程序,则加载2.0的clr。sscoree加载CLR的过程是通过几个导出函数实现的,而clix程序严重依赖这几个函数加载clr和准备.net程序运行环境,这一点我们将在后面看到。

168 ~ 176的代码是一个条件编译代码,启用时,clix在运行.net程序之前让调试器有机会附加到进程上。

177 ~ 266的代码纯粹就是命令行参数处理,其目的就是将命令行里运行参数传递给将要执行的.net程序。如在命令行执行:clix.exe dotNetApp.exe param1 param2;命令行传递给clix的参数列表param1, param2其实是传给要执行的.net程序dotNetApp.exe的,因此177 ~ 266这段代码的目的就是做这件事情。

267行这段代码是整个main函数里最核心的代码,其执行Launch函数实际加载clr和准备.net运行环境,而Launch函数也是通过在147行调用_CorExeMain2函数完成这项工作的。_CorExeMain2就是sscoree.dll的导出函数,这一点可以用dumpbin命令查看:


cd sscli20 cd binaries.x86dbg.rotor dumpbin /exports sscoree.dll

_CorExeMain2函数的源码位于:\clr\src\vm\ceemain.cpp:1622。_CorExeMain2函数只做两件事情,在1646行调用CoInitializeEE确保进程中加载了CLR执行引擎;真正加载.net程序并执行的工作在1659行调用ExecuteEXE完成,而ExecuteEXE最后调用SystemDomain::ExecuteMainMethod完成这项工作。SystemDomain::ExecuteMainMethod的源码位于 \clr\src\vm\appdomain.cpp:2099行。

跟大部分SSCLI源码类似,函数的前后两块代码都是一些条件判断和扫尾操作代码,从2121行开始,SystemDomain::ExecuteMainMethod依次执行如下操作:

1、从2121行开始,确保虚拟机是在system domain里运行的;

2、2133行加载将要执行的.net程序 – 即assembly;

3、2134行分析assembly里的IL格式,确保是一个合法的.net程序;

4、2138 ~ 2143行找到assembly的入口函数点;

5、2148 ~ 2154行为.net程序创建默认的应用程序域(Application Domain);

6、2155 ~ 2168行为.net程序准备寻找依赖Assembly的环境;

7、2168行加载.net程序以及其依赖的Assembly进入当前进程;

8、2169 ~ 2184行为新创建的应用程序域设置一个友好的名字,以便在调试过程中容易识别;

9、2194行执行.net程序的main函数,进入托管执行环境。

.NET框架源码解读之启动CLR的更多相关文章

  1. .NET框架源码解读之准备CLR源码阅读环境

    微软发布了CLR 2.0的源码,这个源码是可以直接在freebsd和windows环境下编译及运行的,请在微软shared source cli(http://www.microsoft.com/en ...

  2. .NET框架源码解读之SSCLI编译过程简介

    前文演示了编译SSCLI最简便的方法(在Windows下): 在“Visual Studio 2005 Command Prompt”下,进入SSCLI的根目录: 运行 env.bat 脚本准备环境: ...

  3. Python Web Flask源码解读(一)——启动流程

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  4. .NET框架源码解读之MYC编译器

    在SSCLI里附带了两个示例编译器源码,用来演示CLR整个架构的弹性,一个是简化版的lisp编译器,一个是简化版的C编译器.lisp在国内用的少,因此这里我们主要看看C编译器的源码,源码位置是:\ss ...

  5. .NET框架源码解读之SSCLI的调试支持

    阅读源码一个比较快的手段就是在调试器里阅读,这样可以在实际运行SSCLI的过程中,通过堆栈跟踪的方式查看完整的程序执行路径. 当在SSCLI环境里执行一个托管程序的时候,堆栈上通常有托管和非托管代码同 ...

  6. jQuery框架源码解读

    1.jQuery 1.9.1 parseJSON: function( data ) { // Attempt to parse using the native JSON parser first ...

  7. swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?

    date: 2018-8-01 14:22:17title: swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?description: 阅读 sowft 框架源码, 了解 sowf ...

  8. Restful 1 -- REST、DRF(View源码解读、APIView源码解读)及框架实现

    一.REST 1.什么是编程? 数据结构和算法的结合 2.什么是REST? - url用来唯一定位资源,http请求方式来区分用户行为 首先回顾我们曾经做过的图书管理系统,我们是这样设计url的,如下 ...

  9. Jfinal启动源码解读

    本文对Jfinal的启动源码做解释说明. PS:Jfinal启动容器可基于Tomcat/Jetty等web容器启动,本文基于Jetty的启动方式做启动源码的解读和分析,tomcat类似. 入口  JF ...

随机推荐

  1. 六.jQuery源码分析之jQuery原型属性和方法

    97 jQuery.fn = jQuery.prototype = { 98 constructor: jQuery, 99 init: function( selector, context, ro ...

  2. RMAN非归档

    改变归档模式到非归档模式: 1)SQL>SHUTDOWN IMMEDIATE; 2)SQL>STARTUP MOUNT; 3)SQL>ALTER DATABASE NOARCHIVE ...

  3. BDE 升级到FireDAC

    BDE  Query Replace Str in files   by cnpack tools TQueryTFDQuery dmdb->qrypub->Open(sql); fdme ...

  4. Java Graphics 2D绘制图片 在Liunx上乱码

    绘图的代码工具类 package com.gwzx.framework.captcha; import java.awt.Color; import java.awt.Font; import jav ...

  5. nginx 配置ajax跨域访问php接口

    在nginx.conf里面,找到server项,并在里面添加如下配置 location ~ \.php?($|/) { #try_files $uri =; #handel cosr by mao a ...

  6. node.js中实现同步操作的3种实现方法

    这篇文章主要介绍了node.js中实现同步操作的3种实现方法,本文用实例讲解一些需要同步操作的情况下,如何编程实现,需要的朋友可以参考下 众所周知,异步是得天独厚的特点和优势,但同时在程序中同步的需求 ...

  7. Spring Cloud Config配置中心的使用

    一.概述 1. 为什么使用? 1> 配置文件太多,不方便维护 2> 配置文件一般都保存这各种明文显示的密码,无法保证配置内容的安全性,也无法做到按权限分配给个人 3> 更新配置项目需 ...

  8. k8s gpu 资源设置

    将所有相同型号显卡的node打上 相同的label kubectl label node ogs-gpu02 gpu_type=k20m 启动device plugin 和app 时: nodeSel ...

  9. TIME_WAIT和CLOSE_WAIT状态区别

    [TIME_WAIT和CLOSE_WAIT状态区别] 常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭. TCP协议规定,对 ...

  10. 64 位 win7 使用PLSQL Developer(转)

    由于 PLSQL Developer 没有64位版本,所以在64位系统上运行该程链接64位Oracle时就会报错,笔者为这个问题纠结了好几天,后来通过请教Google + 动手实践,终于搞定了这个问题 ...