Debugging Assembly loading

Does a referenced assembly get loaded if no types in the assembly are “not used”?The term used is is very subjective. For a developer it would mean that you probably never created an instance or called a method on it. But this does not cover the whole story. You can instead consider what are the reasons for an assembly load occurring. Suzanne’s blog on Assembly loading Failures would give you a good understanding of failures if that is what you are interested in. This post focuses on how to identify what exactly is causing an assembly to load.We in the WCF team are very cautious on introducing assembly dependencies and how how our code paths can cause assembly loads since this impacts the reference set of your process. Images that get loaded during a WCF call can become the cause of slow start up since every assembly is a potential disk look up and larger the number the higher the impact to startup.  As a guidance for quick app startup is that you can eliminate a lot of the unnecessary assemblies from being loaded to speed up application startup if you refactor types properly. To demonstrate the example here is  a simple application with 2 dependencies – For a simple program shown below will “b.dll” be loaded?

Media_httpsajaycomwpw_gaxuy
namespace App{    using a;    using b;    class Program    {        static void Main(string[] args)        {            Invoke();        }        private static void Invoke()        {            TestClass.Helper();        }    }    class TestClass    {        public static FromB testInstance = null;        public static void Helper() {}        public static void Helper(FromA b){}        public static void Helper(FromB b) { }    }}

YES!! Even though TestClass doesn’t actually have an type from b.dll instantiated. There is a type defined which would cause JIT to resolve the type in TestClass when the static method is invoked on that. However a.dll is not loaded because JIT doesn’t need to compile all static methods on the type. Here is the stack when b.dll is loaded. You can see that the field is being resolved which will cause a module load. You can set a break point on module load using sxeld <dllName>

0:000> sxeld b.dll0:000> g(1a18.1a64): Unknown exception - code 04242420 (first chance)ModLoad: 5bb00000 5bb08000   b.dlleax=00000000 ebx=00000000 ecx=00000002 edx=00000000 esi=766e4cc8 edi=0046b65ceip=77a9fc02 esp=0039a668 ebp=0039a6a0 iopl=0         nv up ei pl nz na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206ntdll!ZwMapViewOfSection+0x12:77a9fc02 83c404          add     esp,40:000> kChildEBP RetAddr0039a668 76b6dfae ntdll!ZwMapViewOfSection+0x120039a6a0 6e366ffc KERNELBASE!MapViewOfFileEx+0x810039a6e8 6e36703e clr!CLRMapViewOfFileEx+0x230039a708 6e37366a clr!CLRMapViewOfFile+0x190039a970 6e373745 clr!MappedImageLayout::MappedImageLayout+0x1ce0039a9ac 6e3737b2 clr!PEImageLayout::Map+0x2d0039a9e0 6e366467 clr!PEImage::GetLayoutInternal+0x7c0039aa28 6e3641a8 clr!PEImage::GetLayout+0xdd0039aac0 6e363ce2 clr!RuntimeOpenImageInternal+0x1310039ab04 6e363d6c clr!GetAssemblyMDInternalImportEx+0x9c0039ab1c 6e47dfda clr!CreateMetaDataImport+0x160039ab58 6e47e08c clr!CAssemblyManifestImport::InitAndLoadMetaData+0x4f0039ab88 6e47e610 clr!CreateAssemblyManifestImport+0x670039b24c 6e47f5fa clr!CAsmDownloadMgr::CreateAssembly+0x2080039b5a4 6e47eb8c clr!CAsmDownloadMgr::DoSetupRFS+0xb70039b828 6e47e973 clr!CAsmDownloadMgr::DoSetup+0x22d0039b888 6e47cd09 clr!CAssemblyDownload::DoSetup+0xae0039b8bc 6e47ce9e clr!CAssemblyDownload::DownloadComplete+0xb60039bb24 6e47cf03 clr!CAssemblyDownload::KickOffDownload+0x35e0039bbb4 6e36ae31 clr!CAssemblyName::BindToObject+0x8be0039bc48 6e36aff2 clr!FusionBind::RemoteLoad+0x2290039bcd4 6e36b180 clr!FusionBind::LoadAssembly+0x1160039bf84 6e369e3b clr!AssemblySpec::FindAssemblyFile+0xf40039ccb4 6e367d35 clr!AppDomain::BindAssemblySpec+0x9690039cd58 6e367bc1 clr!PEFile::LoadAssembly+0xbf0039ce10 6e367e63 clr!Module::LoadAssembly+0x1370039d0a4 6e321f02 clr!Assembly::FindModuleByTypeRef+0x2560039d0f4 6e30f8fc clr!ClassLoader::LoadTypeDefOrRefThrowing+0xfb0039d218 6e330a2a clr!SigPointer::GetTypeHandleThrowing+0x9600039d26c 6e330b7d clr!CEEInfo::getFieldTypeInternal+0x8b0039d310 6f864b13 clr!CEEInfo::getFieldInfo+0x35c0039da30 6f85277d clrjit!Compiler::impImportBlockCode+0x36410039da94 6f85291e clrjit!Compiler::impImportBlock+0x7a0039daac 6f85296a clrjit!Compiler::impImport+0x1bf0039dab8 6f8529a7 clrjit!Compiler::fgImport+0x200039dac8 6f853b02 clrjit!Compiler::compCompile+0x450039db04 6f853c1a clrjit!Compiler::compCompileHelper+0x2dd0039db78 6f853d54 clrjit!Compiler::compCompile+0x1e20039dc58 6f8545d9 clrjit!jitNativeCode+0x1540039dc7c 6e3334b6 clrjit!CILJit::compileMethod+0x250039dce0 6e333535 clr!invokeCompileMethodHelper+0x5c0039dd28 6e33357b clr!invokeCompileMethod+0x310039dd90 6e3337e1 clr!CallCompileMethodWithSEHWrapper+0x2e0039e0f8 6e33f817 clr!UnsafeJitFunction+0x3eb0039e1d0 6e33f97f clr!MethodDesc::MakeJitWorker+0x2880039e240 6e3264f6 clr!MethodDesc::DoPrestub+0x49d0039e2b8 6e302dbf clr!PreStubWorker+0x1340039e2e8 6e30297e clr!ThePreStub+0x160039e2f8 6e323bc9 clr!CallDescrWorker+0x340039e374 6e324dfb clr!CallDescrWorkerWithHandler+0x8d0039e400 6e324e64 clr!DispatchCallDebuggerWrapper+0x6f0039e43c 6e328198 clr!DispatchCallSimple+0x4a0039e4b4 6e3280cc clr!MethodTable::RunClassInitEx+0xdb0039ee00 6e3ad21d clr!MethodTable::DoRunClassInitThrowing+0x4e50039ee68 6e3264f6 clr!MethodDesc::DoPrestub+0x11b0039eee0 6e302dbf clr!PreStubWorker+0x1340039ef10 005900c8 clr!ThePreStub+0x160039ef18 0059008c ConsoleApplication1!App.Program.Invoke()+0x180039ef24 6e30297e ConsoleApplication1!App.Program.Main(System.String[])+0x1c0039ef34 6e323bc9 clr!CallDescrWorker+0x340039efb0 6e3246ec clr!CallDescrWorkerWithHandler+0x8d0039f0f4 6e32471f clr!MethodDesc::CallDescr+0x18c0039f110 6e32473d clr!MethodDesc::CallTargetWorker+0x1f0039f128 6e4a863d clr!MethodDescCallSite::Call_RetArgSlot+0x1a0039f290 6e4a8582 clr!ClassLoader::RunMain+0x24c0039f4f8 6e4a8b98 clr!Assembly::ExecuteMainMethod+0xbf0039fa00 6e4a8c24 clr!SystemDomain::ExecuteMainMethod+0x5680039fa58 6e4a8d5c clr!ExecuteEXE+0x580039faa4 6e452e85 clr!_CorExeMainInternal+0x19a0039fadc 716ba791 clr!_CorExeMain+0x4d0039faec 71727f16 mscoreei!_CorExeMain+0x4a0039fafc 71724de3 MSCOREE!ShellShim__CorExeMain+0x990039fb04 766e3677 MSCOREE!_CorExeMain_Exported+0x80039fb10 77ab9d72 KERNEL32!BaseThreadInitThunk+0xe0039fb50 77ab9d45 ntdll!__RtlUserThreadStart+0x700039fb68 00000000 ntdll!_RtlUserThreadStart+0x1b0:000>