Let’s deep dive into silverlight run time and find out how the request is processed
We need fiddler , WinDbg and a browser in Windows OS. We have a simple html page hosted in IIS with a Silverlight control in it as shown below
<body> <div id=”silverlightControlHost”>
<object data=”data:application/x-silverlight-2,” type=”application/x-silverlight-2″>
<param name=”source” value=”ClientBin/SilverlightApplication1.xap”/>
Attach browser to WinDbg, if you are using IE8 then make sure that you are attaching the child process (tabbed browser), use process explorer to identify the child process.
Execute command “.cmdtree <pathname>sld.txt” as shown below; you can download sld.txt from here as shown below
Silverlight runtime by default gets installed under <system drive> \Program Files\Microsoft Silverlight\<version #>
As shown below
We will be interested more in native dll which makes up of Silverlight runtime. .NET library is part of Silverlight CoreCLR.
In order to get the order of the loaded modules of Silverlight runtime, we can execute command “sxe ld” or you can double click on “Break On Loaded Modules” from command tree and browse to html page containing Silverlight xap file.
You need to ignore most of the dlls but the one loaded from “C:\Program Files\Microsoft Silverlight\2.0.40115.0” (Silverlight runtime path on my machine). The order of loaded modules is
Npctrl.dll, agcore.dll, coreclr.dll, .net dlls
You can use any disassembler or ndepends to look at the exported functions or download one from http://www.smidgeonsoft.prohosting.com/pebrowse-pro-file-viewer.html to look at these native dlls
Below is the snapshot for NPCTRL.DLL
NPCTRL.dll is a COM dll which gets loaded in browser when http request is made with silverlight control in it(object tag). Shown below in the fiddler
Browser determines this based on http response since the MIME type in html file is
type=”application/x-silverlight-2″. NPCTRL.dll gets loaded as Silverlight Plug-in.
This occurs before XAP package gets downloaded,
As shown below, you can now clear breakpoints on loaded modules and set breakpoint for each of dll one by one because debugger remembers the last ld settings.
You may want to change the symbols path to Silverlight runtime so that you can set breakpoints on all exported methods (see the above snapshot).
NPCTRL.DLL imports followings from AGCORE.DLL
NPCTRP.DLL first loads AGCORE.DLL. NPCTRL.dll implements CXcpBrowserHost/CommonBrowserHost and it makes a call to agcore!ObtainCoreServices to set the frameworkcallbacks. NPCTRL.DLL also implements CWindowsServices::CreateCLRRuntimeHost. NPCTRL.dll calls NPCTRL!GetCLRRuntTimeHost to load CORECLR.dll . CORECLR.dll is our Silverlight .NET runtime engine, basically stripped down version of MSCORWKS.dll
Once CLRRuntime is created, coreclr will create a domain and load the .net assembly as a private copy using normal assembly binding. CORECLR will use PEImage layout to map the view of file same as .net runtime. Below is the call stack when application domain for coreclr is set up
0220f4d4 04a9b399 System.Activator.CreateInstance(System.String, System.String)
0220f4e8 04a9b349 System.AppDomain.CreateInstance(System.String, System.String)
0220f504 04a9b298 System.AppDomain.CreateInstanceAndUnwrap(System.String, System.String)
0220f51c 04a9b1d8 System.AppDomain.CreateDomainManager(System.String, System.String)
0220f560 04a94d6a System.AppDomain.SetDomainManager(System.Security.Policy.Evidence, System.Security.Policy.Evidence, IntPtr, Boolean)
0220f5b0 04a98dfd System.AppDomain.Setup(System.Object)
Once app domain is set up, ManagedRuntimeHost will be created as shown below from the reflector
This is when coreclr will also set up System.Windows.Threading.DispatcherSynchronizationContext for Single Threaded Apartment (UI). At this point, it will also create a callback handler in AGCORE.DLL. AGCORE.DLL is the Unmanaged version of Silverlight. AGCORE.DLL implements event listener, Setting the visual root and the callback handler is used for communication between CORECLR and AGCORE.
The main interface for communication between CORECLR and AGCORE is MS.Internal.XcpImports(implemented in System.Windows.DLL) XcpImports is the interop layer importing the exports section in AGCORE.dll
Once XcpImports.SetFrameworkCallbacksNative is called to set the callback handler, MS.Internal.FrameworkCallbacks will create System.Windows.DependencyObject.
After dependency object is created, Application object will be created as shown below
0220f2e4 0108008d SilverlightApplication1.App..ctor()
0220f850 026b2e90 System.Reflection.ConstructorInfo.Invoke(System.Object)
0220f860 026b2a98 MS.Internal.TypeProxy.CreateInstance(UInt32)
.net library will be responsible for creating the visual tree and passing the buffer into agcore.dll native code and so on.
when does XAP package get downloaded?
Once NPCTRL.DLL and AGCORE.DLL are loaded, NPCTRL!CommonBrowserHost implements (shown below) npctrl!CommonBrowserHost::OnGotSourceDownloadResponse and this will make a call into agcore!CCoreServices::StartDeploymentTree which in turn calls agcore!CCoreServices::CLR_Startup and finally this will be routed to npctrl!CWindowsServices::CreateCLRRuntimeHost to load CORECLR.DLL, see below for the callstack
kernel32!LoadLibraryW - Will load CORECLR.DLL