Dissecting Silverlight and CoreCLR Runtime on Windows OS using WinDbg – Silverlight Plugin and Silverlight .NET runtime explained

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
<html><head>   <title>SilverlightApplication1</title></head>
<body> <div id=”silverlightControlHost”>
<object data=”data:application/x-silverlight-2,” type=”application/x-silverlight-2″>
<param name=”source” value=”ClientBin/SilverlightApplication1.xap”/>
</object>  </div></body></html>

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

command tree snapshot

Silverlight runtime by default gets installed under <system drive> \Program Files\Microsoft Silverlight\<version #>
As shown below

silverlight runtime installation folder

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 snapshot

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,

fiddler snapshot

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.

command treesnapshot

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

command treesnapshot

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

coreclr 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

Managed Runtime Host snapshot

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

AGCORE.DLL
XCpImports

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
npctrl!GetCLRRuntimeHost
npctrl!CWindowsServices::CreateCLRRuntimeHost
agcore!CCLRHost::Initialize
agcore!CRuntimeHost::Initialize
agcore!CCoreServices::CLR_Startup
agcore!CDeployment::Start
agcore!CCoreServices::StartDeploymentTree
npctrl!CXcpBrowserHost::put_Source
npctrl!CommonBrowserHost::OnGotSourceDownloadResponsetype=”application/x-silverlight-2″

  • H-MaD says:

    Hi, Nice Post!

    I had a question regarding Silverlight 3.0, which introduced a client HTTP stack in addition to the default browser stack: is there a way to specify which HTTP engine (browser or client) handles a request by debugging npctrl.dll?

    [Reply]

    prashant Reply:

    @H-MaD, Sorry I have not looked into client http stack yet and I am not sure about its entry point. May I ask you what is it that you are trying to achieve?

    Thanks,

    [Reply]

    H-MaD Reply:

    @prashant, I am trying to figure out whether a request sent from an unknown Silverlight application was sent using client stack or browser stack.
    I am trying to learn how Silverlight succeeds in managing two totally different contexts for the two HTTP engines (cookie handling, connections, etc…).
    Thanks,

    [Reply]

    H-MaD Reply:

    @prashant, I am trying to figure out whether a request sent from an unknown Silverlight application was sent using client stack or browser stack.
    I am trying to learn how Silverlight succeeds in managing two totally different contexts for the two HTTP engines (cookie handling, connections, etc…).
    Thanks,

    [Reply]

    prashant Reply:

    @H-MaD, okay I understand. I will look into it one of these weekends.

    thanks,

    [Reply]

    January 24, 2010 at 3:42 pm
  • stephanie says:

    I have a desktop notpad file that keeps appearing on my desktop and I’m unable to rid myself of it. It’s “agcore”..Any ideas on how I can remove it permanently or can I?

    [Reply]

    May 20, 2010 at 3:31 pm
  • Chui Tey says:

    Interesting. I was trying to figure out if it is possible to have a private copy of the silverlight runtime on a USB stick. Most of the functionality is provided by the Out of Browser launcher sllauncher.exe.

    However, sllauncher uses COM to look up npctrl.dll, which fails.

    I was hoping Registration Free COM would come to the rescue, and I stripped off the RT_MANIFEST from sllauncher.exe, so that it will use external manifests. However, my RegistrationFree COM-fu was weak, and try as I might I couldn’t get it to work.

    [Reply]

    February 12, 2013 at 5:10 am

Your email address will not be published. Required fields are marked *

*