Inside and Out…

An attempt to understand technology better…

Archive for the ‘CLR’ Category

Enumerating AppDomains – I

Posted by Gaurav Khanna on June 9, 2007

Surprisingly, enumerating AppDomains is not that straightforward. The System.AppDomain type does not expose functionality to enumerate them at all. The way to enumerate them will be to use the V1 Hosting interface, ICorRuntimeHost and then invoke the EnumDomains and NextDomain methods against it to get the list. If you are using CLR 2.0, you needn’t worry as CLR 2.0 does implement the V1 interfaces as well.

 

Below is the snippet that exemplifies the concept (note: AppDomains will only be enumerated in the current process – I will discuss AppDomain enumeration in remote processes later). You can download the source code (VS Solution) from http://www.wintoolzone.com/ListDotNET.aspx?Listtype=5

 

// EnumAppDomains.cpp : Defines the entry point for the console application.
// 
#include "stdafx.h"
#include <windows.h>
#include "mscoree.h"
#import "C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\mscorlib.tlb" raw_interfaces_only
using namespace mscorlib; 
#define EXITONERROR(hr, mesg) \
if (FAILED(hr)) \
{ \
printf("%s\n", mesg); \
ExitProcess(1); \
} 
#define SUCCESSFUL(hr) (SUCCEEDED(hr) && hr != S_FALSE) 
int _tmain(int argc, _TCHAR* argv[])
{
ICorRuntimeHost * pV1HostPtr = NULL;
HRESULT hr = CorBindToRuntimeEx(NULL,
NULL, 0, 
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(LPVOID *)&pV1HostPtr);
EXITONERROR(hr, "Unable to get ICorRuntimeHost*"); 
// Start the runtime
hr = pV1HostPtr->Start();
EXITONERROR(hr, "Unable to start the runtime"); 
// Enumerate the AppDomains
HDOMAINENUM adEnum;
hr = pV1HostPtr->EnumDomains(&adEnum);
EXITONERROR(hr, "Unable to enumerate AppDomains");
// Loop thru the domains
IUnknown * pDomainUnk = NULL;
hr = pV1HostPtr->NextDomain(adEnum, &pDomainUnk);
while(SUCCESSFUL(hr))
{
// Got the IUnknown* to the AppDomain - convert it to AppDomain pointer
_AppDomain * pCurDomain = NULL;
hr = pDomainUnk->QueryInterface(__uuidof(_AppDomain), (VOID**)&pCurDomain);
if (SUCCESSFUL(hr))
{
// Display the name of the AppDomain
BSTR str;
if (SUCCESSFUL(pCurDomain->get_FriendlyName(&str)))
{
wprintf(L"AppDomain: %s\n",str);
}
else
{
printf("AppDomain: unable to get the name!\n");
}
} 
// Loop onto the next Domain
hr = pV1HostPtr->NextDomain(adEnum, &pDomainUnk);
} 
// Stop the runtime
if (pV1HostPtr)
{
pV1HostPtr->Stop();
}
return 0;
} 

Posted in .NET Framework, CLR, Development | Leave a Comment »

Article: Customizing AppDomain Creation

Posted by Gaurav Khanna on February 26, 2007

Did you have a scenario where you wished you could customize the creation of AppDomains? Or, you could control how many AppDomains any code that runs in your application context (e.g. if you are writing a plugin load framework) could create? Or, how about reusing AppDomains for various assemblies?

I have just finished an article on how any of the above scenarios can be accomplished using the System.AppDomainManager type, introduced in .NET Framework 2.0, by intercept AppDomain creation requests.

You can read the article at http://www.wintoolzone.com/articles/Customizing_AppDomain_Creation.aspx and download associated source code from http://www.wintoolzone.com/downloads/Customizing_AppDomain_Creation_src.zip

Posted in .NET Framework, Articles, CLR, Development, Downloads | Leave a Comment »

How the SSCLI [a.k.a. Rotor] managed &quot;new&quot; works

Posted by Gaurav Khanna on February 12, 2007

One of the best ways to understand how the CLR works internally is to have a look at the SSCLI [a.k.a Rotor] source code.

In How the SSCLI [a.k.a. Rotor] managed “new” works, I have used Rotor source code to discuss what happens behind the scenes when you use the managed new operator to instantiate a managed type, discussing implications of object size, how requests from multiple threads are handled, the different validations that are done, when out-of-memory exception is thrown, etc. If you are a managed code developer, you may learn a thing or two that can help you write better code besides understanding how the managed allocation works internally.

Posted in Articles, CLR, Development, Rotor | Leave a Comment »

CLR Profiler for .NET Framework 2.0

Posted by Gaurav Khanna on December 26, 2005

Download it from here.

Posted in .NET Framework, CLR, Downloads, Performance | Leave a Comment »

Adding process enumeration support in Rotor v1.0

Posted by Gaurav Khanna on September 5, 2005

Share Source CLI, better known as Rotor, is one of the best ways to understand how .NET Framework works. And with the source code availability as part of Rotor distribution, its an excellent academic/hobby interest – you can extend it by adding more functionality, or modify the existing one and see how it behaves.

Yesterday, I went about doing the same. One of the functionality which I found missing in Rotor is that of enumerating system process list. .NET Framework’s System.Diagnostics.Process class has methods, like GetProcesses, that allow you to do the same.

So, I went about implementing GetProcesses method overloadsin System.Diagnostics.Process class that allow me to enumerate process list on the local machine only. This required modification in the Platform Adaptation Layer (PAL) of Rotor. Since, I just have it running on Win32 for the moment, I modified the Win32 PAL to implement the support via ToolHelpAPI. Now, on a Windows system, its possible to enumerate the system process list using Rotor, as exemplified by the snippet below:

You can download the updated source files for Rotor v1.0 from http://www.wintoolzone.com/showpage.aspx?url=rotor.aspx. The zipped archive contains Changes for Process Enumeration.txt that indicates where the updated files need to be copied. Once done, rebuild Rotor to get the changes into effect.

using System; 
using System.Diagnostics;

public class EnumProcess
{
    public static void Main()
    {
        Process[] arrProcess = Process.GetProcesses();
        if (arrProcess == null)
        {
            Console.WriteLine("Unable to get process list!");
            return;
        }

        Console.WriteLine("{0} processes enumerated.", arrProcess.Length);

        foreach (Process proc in arrProcess)
            Console.WriteLine("Process ID {0}, Handle: {1}", proc.Id, proc.Handle);
    }
}

Posted in CLR, Downloads, Rotor | Leave a Comment »

Understanding CLR’s Special Threads

Posted by Gaurav Khanna on July 12, 2005

There are multiple special threads which the CLR maintains and executes. Yun Jin talks about them in his blog at http://blogs.msdn.com/yunjin/archive/2005/07/05/435726.aspx.

Must read for those who want to understand CLR better!

Posted in .NET Framework, CLR, Tips | Leave a Comment »

..and ThreadPool.GetMinThreads

Posted by Gaurav Khanna on July 25, 2004

And I am finally done with extending the Rotor’s ThreadPool class. Finished implementing the GetMinThreads method.

Download the source code from http://www.wintoolzone.com/showpage.aspx?url=rotor.aspx.

Posted in CLR, Development, Downloads, Rotor | Leave a Comment »

Rotor – SetMaxThreads, SetMinThreads

Posted by Gaurav Khanna on July 22, 2004

Just finished extending Rotor’s ThreadPool class to support SetMaxThreads and SetMinThreads methods – to modify the extent of the threadpool maintained by the Rotor runtime – just like .NET FX 2.0 has it.

Will post the source code soon…meanwhile, here’s my implementation of SetMinThreadsInternal in Win32ThreadPool.cpp:

/************************************************************************/
// Will be used to set the minimum number of threads in the Rotor Threadpool
// Kumar Gaurav Khanna - 22-Jul-2004
BOOL ThreadpoolMgr::SetMinThreads(DWORD MinWorkerThreads, 
                                     DWORD MinIOCompletionThreads)
{

    if (IsInitialized())
    {
        BOOL result = FALSE;

        // 1) cannot have minimum worker thread limit <=0
        // 2) cannot have minimum worker thread limit equal to 
// or greater than the maximum worker thread limit if ((MinWorkerThreads > 0) && (MinWorkerThreads < MaxLimitTotalWorkerThreads)) { if (MinWorkerThreads <= (DWORD) MinLimitTotalWorkerThreads) { MinLimitTotalWorkerThreads = MinWorkerThreads; result = TRUE; } } return result; } if (InterlockedCompareExchange(&Initialization, 1, 0) == 0) { Initialize(); BOOL result = FALSE; if ((MinWorkerThreads > 0) && (MinWorkerThreads < MaxLimitTotalWorkerThreads)) { if (MinWorkerThreads <= (DWORD) MinLimitTotalWorkerThreads) { MinLimitTotalWorkerThreads = MinWorkerThreads; result = TRUE; } } Initialization = -1; return result; } else // someone else is initializing. Too late, return false { return FALSE; } }

Posted in CLR, Downloads, Rotor | Leave a Comment »