东莞市盛裕绒艺玩具有限公司

东莞市盛裕绒艺玩具有限公司

lzyq858游戏

18509552024
联系方式
全国服务热线: 18509552024

咨询热线:13556085153
联系人:马悠悠
地址:宁夏 银川 市市城区解放东街3号

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

来源:lzyq858游戏   发布时间:2019-11-15   点击量:385

一、什么是应用程序域

操作系统由于其稳定性与可靠性的要求,都会使用隔离层,来确保运行在某个隔离层内的代码不会对其他隔扇层的代码产生影响。如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 sos0:006> !EEVersion*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:WindowsMicrosoft.NETFrameworkv4.0.30319clr.dll - PDB symbol for clr.dll not loaded4.7.3190.0 retailWorkstation modeSOS Version: 4.6.1648.0 retail build0:006> !DumpDomainThe version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.7.3190.0SOS Version: 4.6.1648.0--------------------------------------System Domain: 7230d5a8LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: None--------------------------------------Shared Domain: 7230d258LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: NoneAssembly: 00cb30e8 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00cb2bd0 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll--------------------------------------Domain 1: 00c7f090LowFrequencyHeap: 00c7f4fcHighFrequencyHeap: 00c7f548StubHeap: 00c7f594Stage: OPENSecurityDescriptor: 00c87cb0Name: Sample01.exeAssembly: 00cb30e8 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00cb2bd0SecurityDescriptor: 00cb3060 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00cb6718 [E:WorkspaceDotNetWinDbgInspectCLRSample01inDebugSample01.exe]ClassLoader: 00cb6c18SecurityDescriptor: 00cb6b90 Module Name00be401c E:WorkspaceDotNetWinDbgInspectCLRSample01inDebugSample01.exe

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

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

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

    0:006> !DumpDomain 7230d5a8The version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.7.3190.0SOS Version: 4.6.1648.0--------------------------------------System Domain: 7230d5a8LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: None

    LowFrequencyHeapHighFrequencyHeapStubHeap:.Net程序是建立在中间语言(IL)的基础上的,因此,每个应用程序域都有相就的MSIL代码。在JIT编译成MSIL过程中,JIT编译器需要保存与编译过程相关的数据,如机器代码与方法表(Method Table)等。因此,每个应用程序域都需要创建一定数据的堆(Heap)来存储这些数据。LowFrequencyHeap中则保存的是一些更新、访问较少的数据,HighFrequencyHeap包含的是被访问频繁的数据,而StubHeap中包含的是CLR执行互用性调用 (例如COM互用性或者平台调用)时需要的辅助数据。

    Name:应用程序域名称。

    Assembly:在应用程序域中加载的所有程序集。从输出中来看,应用程序域Sample01.exe中加载了两个程序集:mscorlib.dll、Sample01.exe。其中更包含程序集版本、底层程序集数据结构地址,如Sample01.exe程序集的地址为00c7f090

三、各应用程序域的作用

系统应用程序域

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

共享应用程序域

在共享应用程序域中包含的是与应用程序域无关的代码。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: 7230d5a8LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: None--------------------------------------Shared Domain: 7230d258LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: NoneAssembly: 00df8468 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00df8520 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll--------------------------------------Domain 1: 00dd7da0LowFrequencyHeap: 00dd820cHighFrequencyHeap: 00dd8258StubHeap: 00dd82a4Stage: OPENSecurityDescriptor: 00dd0120Name: Sample02.exeAssembly: 00df8468 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00df8520SecurityDescriptor: 00dfc018 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00dff8d8 [E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe]ClassLoader: 00dff318SecurityDescriptor: 00dfcd60 Module Name00ec401c E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe

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

0:006> !DumpDomainThe version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.7.3190.0SOS Version: 4.6.1648.0--------------------------------------System Domain: 7230d5a8LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: None--------------------------------------Shared Domain: 7230d258LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: NoneAssembly: 00df8468 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00df8520 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll--------------------------------------Domain 1: 00dd7da0LowFrequencyHeap: 00dd820cHighFrequencyHeap: 00dd8258StubHeap: 00dd82a4Stage: OPENSecurityDescriptor: 00dd0120Name: Sample02.exeAssembly: 00df8468 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00df8520SecurityDescriptor: 00dfc018 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00dff8d8 [E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe]ClassLoader: 00dff318SecurityDescriptor: 00dfcd60 Module Name00ec401c E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe--------------------------------------Domain 2: 00e0cf00LowFrequencyHeap: 00e0d36cHighFrequencyHeap: 00e0d3b8StubHeap: 00e0d404Stage: OPENSecurityDescriptor: 00e09fe0Name: NewDomainAssembly: 00df8468 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00df8520SecurityDescriptor: 00dfccd8 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00e17398 [E:WorkspaceDotNetWinDbgInspectCLRSample01inDebugSample01.exe]ClassLoader: 00e21d90SecurityDescriptor: 00dfc128 Module Name011949f4 E:WorkspaceDotNetWinDbgInspectCLRSample01inDebugSample01.exe

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

0:006> !DumpDomainThe version of SOS does not match the version of CLR you are debugging. Pleaseload the matching version of SOS for the version of CLR you are debugging.CLR Version: 4.7.3190.0SOS Version: 4.6.1648.0--------------------------------------System Domain: 7230d5a8LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: None--------------------------------------Shared Domain: 7230d258LowFrequencyHeap: 7230d8ccHighFrequencyHeap: 7230d918StubHeap: 7230d964Stage: OPENName: NoneAssembly: 00aa7a90 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00aa8818 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll--------------------------------------Domain 1: 00a7f410LowFrequencyHeap: 00a7f87cHighFrequencyHeap: 00a7f8c8StubHeap: 00a7f914Stage: OPENSecurityDescriptor: 00a869f0Name: Sample02.exeAssembly: 00aa7a90 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00aa8818SecurityDescriptor: 00aa7a08 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00aab3b8 [E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe]ClassLoader: 00aab050SecurityDescriptor: 00aab5f0 Module Name0097401c E:WorkspaceDotNetWinDbgInspectCLRSample02inDebugSample02.exe--------------------------------------Domain 2: 00ab93d8LowFrequencyHeap: 00ab9844HighFrequencyHeap: 00ab9890StubHeap: 00ab98dcStage: HANDLETABLE_NOACCESSName: NewDomainAssembly: 00aa7a90 [C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dll]ClassLoader: 00aa8818SecurityDescriptor: 00abd780 Module Name6a681000 C:WINDOWSMicrosoft.NetassemblyGAC_32mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllAssembly: 00acdce0 []ClassLoader: 00acde80SecurityDescriptor: 00abcb48 Module Name04cf49f4 Dynamic Module

六、总结

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

参考文献

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

相关产品

COPYRIGHTS©2017 lzyq858游戏 ALL RIGHTS RESERVED 备案号:385