WinDbg探究CLR底层(1) - 应用程序域

一、什么是应用程序域

操作系统由于其稳定性与可靠性的要求,都会使用隔离层,来确保运行在某个隔离层内的代码不会对其他隔扇层的代码产生影响。如Windows通过进程来实现这种隔离机制,所能的可执行代码、数据、以及其它资源都被包含在进程中,系统其他进程通常不允许对它们进行访问。同理、.NET应用程序同样也是被局限在进程内执行,但是.NET还进一步引入了另一种逻辑隔离层,也就是我们这里说的应用程序域(AppDomain)

二、如何查看应用程序域

下面用一个例子看看应用程序域:

using System;

namespace Sample01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World");

            Console.ReadLine();
        }
    }
}

这段代码是一个简单的控制台程序,没有任何逻辑。运行起来,使用WinDbg附加到进程,然后执行以下命令:

0:006> .load sos
0:006> !EEVersion
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll -
PDB symbol for clr.dll not loaded
4.7.3190.0 retail
Workstation mode
SOS Version: 4.6.1648.0 retail build
0:006> !DumpDomain
The version of SOS does not match the version of CLR you are debugging.  Please
load the matching version of SOS for the version of CLR you are debugging.
CLR Version: 4.7.3190.0
SOS Version: 4.6.1648.0
--------------------------------------
System Domain:      7230d5a8
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
--------------------------------------
Shared Domain:      7230d258
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
Assembly:           00cb30e8 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00cb2bd0
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

--------------------------------------
Domain 1:           00c7f090
LowFrequencyHeap:   00c7f4fc
HighFrequencyHeap:  00c7f548
StubHeap:           00c7f594
Stage:              OPEN
SecurityDescriptor: 00c87cb0
Name:               Sample01.exe
Assembly:           00cb30e8 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00cb2bd0
SecurityDescriptor: 00cb3060
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00cb6718 [E:\Workspace\DotNet\WinDbgInspectCLR\Sample01\bin\Debug\Sample01.exe]
ClassLoader:        00cb6c18
SecurityDescriptor: 00cb6b90
  Module Name
00be401c    E:\Workspace\DotNet\WinDbgInspectCLR\Sample01\bin\Debug\Sample01.exe

通过!DumpDomain命令输出,可以看到,这个示例执行程序所在进程中3个应用程序域,SystemSharedDomain 1。其中,Domain 1是默认的应用程序域,它的名字就是映像本身的名字(Sample01.exe)。

在每个应用程序域的输出消息中包含以下内容:

  1. System Domain: 指向应用程序域的指针。这个指针可以作为DumpDomain命令的输入参数,以得到指定应用程序域的信息,如:

    0:006> !DumpDomain 7230d5a8
    The version of SOS does not match the version of CLR you are debugging.  Please
    load the matching version of SOS for the version of CLR you are debugging.
    CLR Version: 4.7.3190.0
    SOS Version: 4.6.1648.0
    --------------------------------------
    System Domain:      7230d5a8
    LowFrequencyHeap:   7230d8cc
    HighFrequencyHeap:  7230d918
    StubHeap:           7230d964
    Stage:              OPEN
    Name:               None
  2. LowFrequencyHeapHighFrequencyHeapStubHeap:.Net程序是建立在中间语言(IL)的基础上的,因此,每个应用程序域都有相就的MSIL代码。在JIT编译成MSIL过程中,JIT编译器需要保存与编译过程相关的数据,如机器代码与方法表(Method Table)等。因此,每个应用程序域都需要创建一定数据的堆(Heap)来存储这些数据。LowFrequencyHeap中则保存的是一些更新、访问较少的数据,HighFrequencyHeap包含的是被访问频繁的数据,而StubHeap中包含的是CLR执行互用性调用 (例如COM互用性或者平台调用)时需要的辅助数据。
  3. Name:应用程序域名称。
  4. Assembly:在应用程序域中加载的所有程序集。从输出中来看,应用程序域Sample01.exe中加载了两个程序集:mscorlib.dll、Sample01.exe。其中更包含程序集版本、底层程序集数据结构地址,如Sample01.exe程序集的地址为00c7f090

三、各应用程序域的作用

系统应用程序域

  1. 创建其他两个应用程序域(共享应用程序域和默认应用程序域)。
  2. 将mscorlib.dll加载到共享应用程序域中(在下面将进一步讨论)。
  3. 记录进程中所有其他的应用程序域,包括提供加载/卸载应用程序域等功能。
  4. 记录字符串池中的字符串常量,因此允许任意字符串在每个进程中都存在一个副本。
  5. 初始化特定类型的异常,例如内存耗尽异常,栈溢出异常以及执行引擎异常等。

共享应用程序域

在共享应用程序域中包含的是与应用程序域无关的代码。mscorlib.dll将被加载到这个应用程序域中(由系统应用程序域负责加载),此外还包括在System命名空间中的一些基本类型(例如String、enum、ValueType、Array等)。在大多数情况下,非用户代码(non-user code)将被加载到共享应用程序域中,不过也有一些机制可以将用户代码(user code)加载到共享应用程序域中。启用了CLR的应用程序域可以通过加载器的优化属性来注入用户代码。

默认应用程序域

通常,.NET程序在默认应用程序域中运行。位于默认应用程序域中的所有代码都只有在这个域中才是有效的。由于应用程序域实现了一种有逻辑并且可靠的边界,因此任何跨越应用程序域的访问操作都必须通过.NET远程对象来进行。

四、动态创建、卸载应用程序域

前面我们看到程序启动时,系统帮我们创建的默认应用程序域,然后手动创建应用程序域也是可以的,代码如下:

using System;

namespace Sample02
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Before CreateDomain");
            Console.ReadLine();

            AppDomain domain = AppDomain.CreateDomain("NewDomain");

            Console.WriteLine("After CreateDomain, Before Unload");
            Console.ReadLine();

            AppDomain.Unload(domain);

            Console.WriteLine("After Unload");
            Console.ReadLine();
        }
    }
}

程序开始运行时:

有三个应用程序域:System Domain、Shared Domain、Domain 1

0:006> !DumpDomain
--------------------------------------
System Domain:      7230d5a8
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
--------------------------------------
Shared Domain:      7230d258
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
Assembly:           00df8468 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00df8520
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

--------------------------------------
Domain 1:           00dd7da0
LowFrequencyHeap:   00dd820c
HighFrequencyHeap:  00dd8258
StubHeap:           00dd82a4
Stage:              OPEN
SecurityDescriptor: 00dd0120
Name:               Sample02.exe
Assembly:           00df8468 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00df8520
SecurityDescriptor: 00dfc018
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00dff8d8 [E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe]
ClassLoader:        00dff318
SecurityDescriptor: 00dfcd60
  Module Name
00ec401c    E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe

Enter继续执行,多一个应用程序域Domain 2

0:006> !DumpDomain
The version of SOS does not match the version of CLR you are debugging.  Please
load the matching version of SOS for the version of CLR you are debugging.
CLR Version: 4.7.3190.0
SOS Version: 4.6.1648.0
--------------------------------------
System Domain:      7230d5a8
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
--------------------------------------
Shared Domain:      7230d258
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
Assembly:           00df8468 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00df8520
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

--------------------------------------
Domain 1:           00dd7da0
LowFrequencyHeap:   00dd820c
HighFrequencyHeap:  00dd8258
StubHeap:           00dd82a4
Stage:              OPEN
SecurityDescriptor: 00dd0120
Name:               Sample02.exe
Assembly:           00df8468 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00df8520
SecurityDescriptor: 00dfc018
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00dff8d8 [E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe]
ClassLoader:        00dff318
SecurityDescriptor: 00dfcd60
  Module Name
00ec401c    E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe

--------------------------------------
Domain 2:           00e0cf00
LowFrequencyHeap:   00e0d36c
HighFrequencyHeap:  00e0d3b8
StubHeap:           00e0d404
Stage:              OPEN
SecurityDescriptor: 00e09fe0
Name:               NewDomain
Assembly:           00df8468 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00df8520
SecurityDescriptor: 00dfccd8
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00e17398 [E:\Workspace\DotNet\WinDbgInspectCLR\Sample01\bin\Debug\Sample01.exe]
ClassLoader:        00e21d90
SecurityDescriptor: 00dfc128
  Module Name
011949f4    E:\Workspace\DotNet\WinDbgInspectCLR\Sample01\bin\Debug\Sample01.exe

再次按Enter继续执行,应用程序域Domain 2中的Sample01.exe被卸载, 目前还没查到为什么Domain 2 没被整体卸载,我猜想是因为mscorlib.dll还在还在使用。

0:006> !DumpDomain
The version of SOS does not match the version of CLR you are debugging.  Please
load the matching version of SOS for the version of CLR you are debugging.
CLR Version: 4.7.3190.0
SOS Version: 4.6.1648.0
--------------------------------------
System Domain:      7230d5a8
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
--------------------------------------
Shared Domain:      7230d258
LowFrequencyHeap:   7230d8cc
HighFrequencyHeap:  7230d918
StubHeap:           7230d964
Stage:              OPEN
Name:               None
Assembly:           00aa7a90 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00aa8818
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

--------------------------------------
Domain 1:           00a7f410
LowFrequencyHeap:   00a7f87c
HighFrequencyHeap:  00a7f8c8
StubHeap:           00a7f914
Stage:              OPEN
SecurityDescriptor: 00a869f0
Name:               Sample02.exe
Assembly:           00aa7a90 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00aa8818
SecurityDescriptor: 00aa7a08
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00aab3b8 [E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe]
ClassLoader:        00aab050
SecurityDescriptor: 00aab5f0
  Module Name
0097401c    E:\Workspace\DotNet\WinDbgInspectCLR\Sample02\bin\Debug\Sample02.exe

--------------------------------------
Domain 2:           00ab93d8
LowFrequencyHeap:   00ab9844
HighFrequencyHeap:  00ab9890
StubHeap:           00ab98dc
Stage:              HANDLETABLE_NOACCESS
Name:               NewDomain
Assembly:           00aa7a90 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00aa8818
SecurityDescriptor: 00abd780
  Module Name
6a681000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

Assembly:           00acdce0 []
ClassLoader:        00acde80
SecurityDescriptor: 00abcb48
  Module Name
04cf49f4    Dynamic Module

六、总结

一直听说应用程序域,但对其概念、作用不甚了解,因此结合WinDbg来试图对其进行深入理解,加深印象,后续系列会继续使用WinDbg对CLR底层进行研究。

参考文献

  1. 《.NET高级调试》
  2. WinDbg 命令三部曲

原文地址:https://www.cnblogs.com/tonqiang/p/9786163.html

时间: 2024-08-05 02:24:09

WinDbg探究CLR底层(1) - 应用程序域的相关文章

探究PHP底层

探究PHP底层 1.PHP是什么? PHP 指的是我们从外面看到的一套完整的系统.这听起来有点糊涂,但其实并不复杂(PHP4 内部结构图).从功能上来分:我们可以分为三部分: 1. 解释器部分(Zend 以引擎),负责对输入代码的分析.翻译和执行: 2. 功能性部分(PHP功能函数以及扩展),负责具体实现语言的各种功能(比如它的函数等等): 3. 接口部分(SAPI),负责同 WEB 服务器的会话等功能. Zend包括了第一部分的全部和第二部分的局部,PHP内核 包括了第二部分的局部和第三部分的

CLR寄宿和应用程序域

Win实际上将CLR作为一个COM服务器实现在一个DLL内,即为CLR定义了标准的COM接口,并为该接口和COM服务器分配一GUID,安装FrameWork时表示CLR的COM服务器被注册到注册表内.任何Win APP都可以寄宿CLR. 一个PC可安装多个版本的CLR,但是只有一个版本(最新版本)的MSCorEE.dll(判断创建何版本的CLR,而CLR COM服务器在MSCorwks.dll和MSCorSvr.dll内)(64位上有两个:For 32B/For 64B).且其知道如何找到以前版

Clr Via C#读书笔记---CLR寄宿和应用程序域

#1 CLR寄宿: 开发CLR时,Microsoft实际是将他实现成包含在一个dll中的COM服务器.Microsoft为CLR定义了一个标准的COM接口,并为该接口和COM服务器分配了GUID.安装.NET Framework时,代表CLR的COM服务器在Windows注册表中注册. 任何Windows应用程序都可以寄宿CLR,非托管宿主应该调用MetaHost.h文件中声明的CLRCreateInstance函数,该函数是在MSCoreEE.dll文件中实现的,该dll被称为"垫片"

VS2012中使用SOS调试CLR

之前看了<用WinDbg探索CLR世界>的一些列文章,发现SOS真的是一个非常好的调试.net的工具, 然后又惊喜的在http://blogs.msdn.com/b/mariohewardt/archive/2012/06/05/visual-studio-2012-and-windbg-integration.aspx 上看到原来windbg已经被集成 到VS2012的IDE中.本文主要讲解在VS2012中调用SOS的基本步骤 1 SOS是一个非托管的DLL,要使用SOS调试,首先需要打开本

重温C# clr 笔记总结

重温C# clr 笔记总结 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-13我要评论 本篇文章是对以前学习C# clr做的一些笔记,现在拿出来和大家分享下,希望需要的朋友能参考一下 1: .net framework 由两个部分组成:CLR 和 FCL. 2:在CLR中,所有错误都是通过异常来报告的. 3:智能感知功能主要是靠解析元数据实现的. 4:允许在不同语言之间方便的切换,并对各种语言进行紧密集成是CLR的出色特性. 5:一个方法只有在首次运行时才会由于jit造成一定的

CLR是如何被加载并工作的

当运行Windows应用程序的时候,CLR总是默默地为服务着.CLR到底是如何被加载并运行呢? 首先,Microsoft专门为CLR定义了一个标准的COM接口. 安装某个版本的.NET Framework,CLR被包含在DLL中,作为COM服务器在Windows注册表中注册. 一台电脑上可能安装多个版本的CLR.打开开发人员命令提示,输入CLRVer.exe,可以看到当前电脑上安装的CLR版本. 比如,在C:\Windows\Microsoft.NET\Framework\v2.0.50727文

CLR Profiler 性能分析工具 (转)

原文地址:http://www.cnblogs.com/kevinlzf/archive/2010/11/12/1876066.html 下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=16273  CLR Profiler for .NET Framework 4 最近关注程序性能的优化方面,本想写篇CLRProfiler的简要文档,看到pengpeng已写好,那就转载好了,偷偷懒. .Net的尽管拥有非常强大调试器,但

小码哥iOS底层原理班怎么样

众所周知 小码哥的iOS是不错的,对于很多人来说自己从事iOS就是从小码哥开始的,随着发展现阶段的iOS并不如之前那么火热了,那么还有学习iOS的必要呢?回答是肯定的,一句老话:活到老学到老,人想要进步想要更好地生活,那么是离不开学习的.那么现在告诉大家个好消息,iOS底层原理班开班啦!MJ亲授,感兴趣的小伙伴们不要错过了!课程亮点1.市面**iOS高级开发课程,由MJ老师亲自研发,全程精心实力打造.2.为iOS开发者量身打造,深入研究iOS底层的方方面面.掌握了底层,你会发现其他的编程语言.操

NET经典书籍必读

C#与.NET框架,入门 + 进阶 + 精通,外加并发编程实例,10本C#图书,一本都不能少. 1.<Learning hard C#学习笔记> 作者:李志  书号:978-7-115-38292-4  定价:49.00元  开本:16  页数:304 博客园超人气博主.微软MVP.资深.NET软件开发工程师Learning hard告诉你怎么学习C#!一书在手,C#不愁! “本书是作者亲身学习经历的真实总结,很适合C#和.NET初学者.Web开发工程师以及计算机专业的学生阅读.作者从不爱学习