托管 EXE 啟動經歷:PE Loader → MSCOREE.DLL → CLR 初始化 → 建立預設 AppDomain → 載入 MSCORLIB → 載入應用程式組件 → JIT 編譯進入 Main。本節逐階段剖析關鍵動作與載入順序。
完整啟動流程
- PE Loader 載入 EXE,解析 PE Header Data Directory Table,發現 CLR Header 非零 → 載入
MSCOREE.DLL 並呼叫 _CorExeMain()
- Windows XP/2000 差異:XP 前版本由 Loader 直接 JMP 至 Import Address Table 中的
_CorExeMain (指令 FF 25 00 20 40 00)
- _CorExeMain 判斷 CLR 版本 → 啟動 CLR
- CLR 初始化:建立進程、記憶體空間、執行緒池、**預設應用程式域 (Default AppDomain)**
- 載入 MSCORLIB.DLL 及核心模組
- Class Loader 載入核心型別 (依序):
- System.Object
- System.ICloneable
- System.Collections.IEnumerable
- …
- System.AppDomain
- System.LoaderOptimization
- System.Runtime.Remoting.Proxies.__TransparentProxy
註:僅載入當前必要型別,非全量載入。
- 建立主執行緒,觸發載入:
- System.Threading.Monitor
- System.IAppDomainSetup / AppDomainSetup
- System.Char
- System.Runtime.InteropServices.RuntimeEnvironment
- System.RuntimeFieldHandle
- System.Runtime.CompilerServices.RuntimeHelpers
- System.Environment
- 載入應用程式組件至 AppDomain
- 進入 Main(),JIT 編譯 IL 為原生碼執行
關鍵觀察點
- **MSCOREE.DLL** 是托管/非托管邊界的橋樑,導出
_CorExeMain、CorBindToRuntimeEx 等關鍵入口
- **Default AppDomain** 為進程級單例,生命週期等同進程
- **核心型別載入順序** 反映 CLR 內部相依圖 (Object → 介面 → AppDomain → Remoting 基礎)
- **主執行緒建立** 觸發同步化、環境、執行緒池等基礎設施型別載入
除錯技巧:在 Visual Studio 啟用「非受控碼偵錯」並設定符號伺服器,可單步進入 MSCOREE.DLL 觀察 CLR 啟動細節。
作者:玄魂
出處:https://www.cnblogs.com/xuanhun/