NVARCHAR and the Oracle string aggregate function to perform concatenation
December 31st, 2009My colleague Janice had a lot of fun while trying to concat NVARCHAR in oracle and she happens to share her findings with us. Hopefully, this will be helpful for someone
Just fyi…
I needed to create a string aggregate function for concatenation in Oracle. For example, given a user table where each record contains DepartmentCode and UserID, I would like to roll up the multiple UserIDs into one field with comma, etc separators.
| DepartmentCode | Users |
| 0 | User1, user2, user3, User4, User5 |
I found this nice summary of the problem along with six(6) potential solutions: http://www.oracle-base.com/articles/10g/StringAggregationTechniques.php
Bottom line…these techniques worked when the data involved was VARCHAR2 (1-byte char), . When I tried using NVARCHAR2 (multi-byte chars), I could not get all of the techniques to work. Here are my findings…
________________________________________
1. WMSYS.WM_CONCAT – This seems to be a slightly undocumented built-in function. Who knew? I am uncertain if it is fully supported by Oracle or not.
VARCHAR2: (Works!)
NVARCHAR2: (Doesn’t work. Returns nulls.)
2. Specific function – Needs a custom function for each string you might want to aggregate.
VARCHAR2: (Works!)
NVARCHAR2: (Works!)
3. Generic function with ref cursor – Only needs one function added. Usage in query is easy to understand.
VARCHAR2: (Works!)
NVARCHAR2: (Doesn’t work. Returns nulls.)
4. User defined aggregate function – Needs a type, type body, and function added. Support code is not obvious. Usage in query is easy to understand.
VARCHAR2: (Works!)
NVARCHAR2: (Doesn’t work. Returns nulls.) Note that when I changed the VARCHAR2 types to NVARCHAR2 in the sample code, I received a runtime error.
5. ROW_NUMBER() and SYS_CONNECT_BY_PATH functions – Needs nothing added. Query usage is by far the most complicated, but it certainly works.
VARCHAR2: (Works!)
NVARCHAR2: (Works!)
6. COLLECT function – Needs a type and a function added. Query usage is easy to understand.
VARCHAR2: (Works!)
NVARCHAR2: (Doesn’t work. Returns nulls.) Note that when I changed the VARCHAR2 types to NVARCHAR2 in the sample code, I received a runtime error.
________________________________________
NOTE: In all of the NVARCHAR2 examples that didn’t work, I tried a variety of explicit type conversions, TO_CHAR, TRANSLATE USING, etc. and nothing helped.
DeepZoom demo download - Uploading images and the Auto DeepZoom xap generation
September 14th, 2009Click here to download the solution
Below is the logical architecture

Click here to download the solution
DeepZoom.sln - visual studio 2008 c# solution includes all the projects. Make sure you have the silverlight 3 tools for visual studi0 2008 installed(www.silverlight.net)
Solution contains the following projects
WebApplication Tier Project
DZWebSite Project - Sample Silverlight 3 App to upload image
DZWebSite.Web Project - Sample html/aspx page to host DZWebSite silverlight control
WCF Service
DataTransferService project - WCF Service which implements IStreamService ServiceContract and UploadFileMessage DataContract
Service Libraries(Windows Service or ConsoleApp)
Utility project - implements a syncqueue and a thread helper
DeepZoomService.Common project - implements DynamicService and FileSystemWatcherBase
DynamicService.cs - implements dynamic windows service using reflection and the configuration file
FileSystemWatcherBase.cs - abstract class for file system
DZService Project - library implements all the services, deepzoom image generation
Windows Service
DeepZoomWindowsService Project - .NET Windows Service functionality same as console app but part of windows SCM
DeepZoom Package
DeepZoom Project - silverlight control without xaml file, responsible for creating MultiScaleImage control and setting the source for deepzoom xml file. You can also inject code at runtime to change the zoom icon or other parameters
TestHarness
DeepZoomConsoleApp Project - Running services in a Console App(easier for debugging), no need to deploy. Instantiates the services as configured in app.config file, by default there are 2 services configured (ImageService and MaintenanceService)
DTServiceConsoleHost Project - test app for testing WCF service
READ ME
Please do the followings if you just want to run it after downloading
1. create a web site (http://localhost/streamsvs) with physical path set to “\DeepZoomService\DataTransferService\ ” to host WCF Upload Service
2. Create a website with physical path “DZWebSite.Web” to browse to Silverlight client app to upload a file
3. Download folder.zip for folder structure used by WCF/Windows/Console service to write and process uploaded images. By default, “C:\DeepZoomService\Customers\TestCustomer” is used by WCF service for uploaded files. “C:\DeepZoomService\Host\TestCustomer” is used by Windows/Console service to generate deepzoom package and the path for testpage
4. Create a site http://localhost/dzpreview/TestCustomer with physical path “C:\DeepZoomService\Host\TestCustomer”, this site is used to host generated deepzoom package in a test page. The link for test page is generated on silverlight client page once the file is uploaded.
5. Execute “\DeepZoomService\DeepZoomConsoleApp\bin\Debug\DeepZoomConsoleApp.exe” to execute the service to monitor the file system and to process the uploaded images to deepzoom package
The best way to start looking into it is by debugging DeepZoomConsoleApp project
Guidance to Developing SharePoint Applications
September 10th, 2009If you are one of those who like the best practices and the guidance from microsoft patterns and practices group, check this out on msdn
Guidance for building collaborative applications that extend your LOB systems
I understand there are quite a few people who detest Microsoft Patterns and Practices
. Sometime, I don’t like the MSDN documentation.
ASP.NET App Slow Response and Application Pool/AppDomain Recycle, Event message: Application is shutting down. Reason: Unknown - Windows Server 2003
August 30th, 2009Scenario
From time to time, asp.net application response is very slow on Windows Server 2003
Some rants and the resolution
After turning on recycle events, logged message in application event log was Event message: Application is shutting down. Reason: Unknown. Slow response is always timed with this message in the application event log so that confirmed that Application Pool is terminating so no wonder asp.net response is slow from time to time.
However, the only missing piece was why? Since, the Reason is unknown :-). This application pool is configured for web garden with 6 app pools in it so we decided to attach debugger in production box to 2 worker processes.
If you are just starting out with debugging or have not read John Robbins Book on debugging, I would like to stress the followings when using debugger in production environment
1. By Default, ADPlus writes the call stack on first-chance exception. Walking call stack also results in Symbol loading, symbol loading along with the stack walking causes a performance hit when a debugger is attached. The last thing you want in production environment is to cause performance hit because of debugger.
2. Don’t just use ADPlus script to attach a debugger to the worker process by name because it will attach the debugger to each worker process in your production server causing further performance hit.
3. Don’t use DebugDiag in production environment unless you really have a good reason for it.
The reason I am stressing about these points is because I noticed someone following all the worst practices in production environment while debugging.
The best practice is to use adplus configuration file to attach to a worker process and preferably by worker process id.
Identifying the issue
First of all, I would like to mention that Tess has excellent blog on AppDomain recycle http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx
We just needed to find out the reason for AppPool shutdown.
Our goal is to attach a debugger to one worker process to generate a memory dump on crash and another goal is, ctrl+c in debugger console should not kill the worker process. We used optimized ADPlus Config file for production environment as shown below
<ADPlus>
<Settings>
<RunMode>CRASH</RunMode>
<Option>Quiet</Option>
<OutputDir> c:\dumps </OutputDir>
<ProcessID> 2684 </ProcessID>
</Settings>
<Exceptions>
<Option> NoDumpOnFirstChance </Option>
<Config>
<Code> AllExceptions </Code>
<Actions1> Log </Actions1>
<Actions2> FullDump; </Actions2>
<ReturnAction1> GN </ReturnAction1>
<ReturnAction2> Q </ReturnAction2>
</Config>
</Exceptions>
</ADPlus>
once we have the crash dump, just dump the httpruntime object to find out the shutdown reason and the call stack as shown below
at System.Web.HttpRuntime.OnCriticalDirectoryChange(Object sender, FileChangeEvent e)
at System.Web.FileChangesMonitor.OnSubdirChange(Object sender, FileChangeEvent e)
at System.Web.DirectoryMonitor.FireNotifications()
at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
at System.Web.Util.WorkItem.OnQueueUserWorkItemCompletion(Object state)
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 67576(0×107f8) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: Directory rename change notification for ‘C:\Inetpub\<>\<>’.
Web dir change or directory renameAppDomain is shutting down because of directory rename.
There are thousands of folders under the root website and after talking to customer I learnt that this is indeed the case.
Resolution
After googling or binging, I found out that there is no resolution and this was implemented in asp.net 2.0. AppDomain will recycle on directory rename or delete. However, I did come across a
Microsoft KB http://support.microsoft.com/kb/911272 which talks about changing this behavior from registry setting. The bad news is changing the registry setting [HKEY_LOCAL_MACHINE\SOFTWARE\
ASP.NET\"FCNMode"=dword:00000001 doesn't work. Although, KB article does suggest you to contact Microsoft support for hot fix but also suggests that it will be addressed in the next .NET SP.
OnFileChange(FileAction, String, DateTime)
OnCriticaldirChange(Object, FileChangeEvent)
OnSubdirChange(Object, FileChangeEvent)
Another cause of AppDomain recycle is overwhelming amount of file change notification but microsoft apparently fixed in .net 2.0 hot fix so who knows.
HttpRuntime also implements another method to monitor the directories
internal void StartListeningToLocalResourcesDirectory(VirtualPath virtualDir) { if (!this.IsFCNDisabled && ((this._callbackRenameOrCriticaldirChange != null) && (this._dirMonSpecialDirs != null))) { |
You will notice, how it checks for FCNDisabled which should have been the registry key since it return (this._FCNMode == 1);
All these settings are set in
internal FileChangesMonitor() { UnsafeNativeMethods.GetDirMonConfiguration(out this._FCNMode);
FCNMode value comes from native dll (webengine.dll)
[DllImport("webengine.dll")] internal static extern void GetDirMonConfiguration(out int FCNMode); |
Since, HttpRuntime controls the file monitoring so get the DirectoryMonitor object and calls StopMonitoring on it. Another way to probably implement is getting the FileChangesMonitor object and setting the FCNMode to 1 or setting the _dirMonSpecialDirs to null.
protected void Application_Start(object sender, EventArgs e)
{
System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime)
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
object o = p.GetValue(null, null);
System.Reflection.FieldInfo f = o.GetType().GetField(”_dirMonSubdirs”,
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);
object monitor = f.GetValue(o);
System.Reflection.MethodInfo m = monitor.GetType().GetMethod(”StopMonitoring”,
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
m.Invoke(monitor, null);
}
{
HttpRuntime runtime = (HttpRuntime)typeof(System.
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
if (runtime == null)
return;
string shutDownMessage = (string)runtime.GetType().InvokeMember(”_shutDownMessage”,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);
string shutDownStack = (string)runtime.GetType().InvokeMember(”_shutDownStack”,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);
if (!EventLog.SourceExists(”.NET Runtime”))
{
EventLog.CreateEventSource(”.NET Runtime”, “Application”);
}
EventLog log = new EventLog();
log.Source = “.NET Runtime”;
log.WriteEntry(String.Format(”\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}”,
shutDownMessage,
shutDownStack),
EventLogEntryType.Error);
}
Important Note
Microsoft KB http://support.microsoft.com/kb/911272 which talks about changing this behavior from registry setting doesn’t work in Windows Server 2003 but it does work on Windows Server 2008/R2 with IIS7 integrated/classic pipeline. The best way to address this issue is by modifying the registry key otherwise file handles don’t get released when dirMonSpecialDirs is set to null using reflection
visual studio 2010 and .net 4.0 series from his guness
August 28th, 2009LoadLibrary failed, Win32 error 0n193 “%1 is not a valid Win32 application.” Please check your debugger configuration and/or network access.
July 29th, 20090:000> .loadby sos coreclr
The call to LoadLibrary(c:\Program Files (x86)\Microsoft Silverlight\3.0.40624.0\sos) failed, Win32 error 0n193
“%1 is not a valid Win32 application.”
Please check your debugger configuration and/or network access.
Make sure you are not using WinDbg 64 bit version. Silverlight is not 64 bit yet so even if you have a browser running on 64 bit os, sos dll for silverlight coreclr will fail to load on WinDbg 64 bit. Analyze your dump with WinDbg x86 version. I have WinDbg 32 bit and 64 bit both installed on my vista 64 bit os, although I still prefer XP or may be windows 7 from now on.
ProcDump sysiternals tool - really really helpful to create a memory dump based on CPU Usage
July 28th, 2009As described in Sysinternals documentation http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx
ProcDump is a command-line utility whose primary purpose is monitoring an application for CPU spikes and generating crash dumps during a spike that an administrator or developer can use to determine the cause of the spike. ProcDump also includes hung window monitoring (using the same definition of a window hang that Windows and Task Manager use) and unhandled exception monitoring. It also can serve as a general process dump utility that you can embed in other scripts.
You don’t need to write your own utility to create a memory dump by monitoring performance counter. Don’t forget to use the switch “-ma” to dump full memory(especially for .net app) because by default it only dumps thread and handle.
This is really helpful to get a memory dump based on CPU usage and we could probably get the memory dump without using ADPlus in most of the cases.
syntax to dump full memory given process id is
procdump <process id> -ma
syntax to dump full memory given process id and cpu usage 80%(threshold)
procdump <process id> -ma -c 80
Silverlight DeepZoom Service Demo Project - Silverlight Client/WCF Upload/DeepZoom XAP package
July 24th, 2009I was working on a poc (proof of concept) to write a DeepZoom Service using Silverlight. The idea is to provide a deep zoom service which will allow any client to consume a deep zoom service to upload an image or images to a server and the client can embed deepzoom image without worrying about storage / location and the service can be integrated in an ecommerce app. I thought I will share this POC here, in case anyone needs the similar service.
Below are the steps I followed
1. Write a windows service to be installed on a client machine with a configurable folders which can be monitored to upload images using WCF Upload Service.
2. Write a web user interface which can be hosted on any webserver to upload an image, I used an html file with silverlight control hosted on Apache Web Server, it allows user to upload an image. once the image is uploaded, it publishes the link to preview the deepzoom image
Download the client source code here
3. Write a WCF Upload service to used by silverlight client hosted on apache server
Download the wcf upload service source code here
4. Write a Windows Service which runs on a server and monitor the configured folder to watch for uploaded images. As images are uploaded to server, it does the followings
a. Generate deep zoom images using DeepZoomTool library(installed with deepzoomcomposer)
b. Move the file for back up
c. Create a xap package with deepzoomimage
d. Generate a test html page hosting the above xap package
5.In order to embed deepzoom image in a page, all you need to do is include a div tag and specify the location of .xap file which will be the http://<deepzoomservice url>/<some unique id to identify each user or a customer>/imagename/imagename.xap
<div id=”silverlightControlHost” style=”height: 100%;”>
<object data=”data:application/x-silverlight,” type=”application/x-silverlight-2″ width=”100%” height=”100%”>
<param name=”source” value=”<uri>/<imagename>/<imagename>.xap”/>
<param name=”onerror” value=”onSilverlightError” />
<param name=”background” value=”white” />
<param name=”minRuntimeVersion” value=”2.0.31005.0″ />
<param name=”autoUpgrade” value=”true” />
</object>
</div>
Silverlight assembly(to host deepzoom image) can be manipulated by injecting IL without needing to recompile the code if needed.
I have not made the windows service source code and xap package generator available yet because it is still under progress but a very simple implementation to generate deepzoom images with default values is nothing more than making call to deepzoom api. Although, DeepZoom apis are a little more involved for finer control of deep zoom image generation.
new Microsoft.DeepZoomTools.ImageCreator().Create(metadata.Source, metadata.Destination); generates the deepzoom image
I can make it available for download, in case anyone is interested.
Silverlight 3 OutOfBrowser(OOB) behind the scenes Explained, how to host a silverlight xap package OOB style without installing it - read/modify silverlight OOB metadata
July 17th, 2009You can find a sample on www.silverlight.net or google(bing) it. The purpose of this post is not to show you how to create a Out Of Browser(OOB) application using visual studio / Silverlight but what happens behind the scene and how you can re-use a silverlight xap package to deploy it on any machine by xcopy or a media drive and run it as a desktop application out of browser style.
First of All, creating a Silverlight Out of Browser Application is one line of code and the change in deployment manifest. Please refer to http://timheuer.com/blog/archive/2009/03/18/silverlight-3-offline-update-framework.aspx to understand silverlight offline/update behavior
In order to support Out of Browser in Silverlight, you just need to call Application.Current.Install() on user action as shown below.
private void Button_Click(object sender, RoutedEventArgs e)
{
Application.Current.Install();
}
When you install the application, it downloads the content(xap package) and generate the html file to host silverlight along with some metadata. Everything is generated at isolated storage, which will be the followings in Windows XP and 2003bi
<systemdrive>:\Documents and Settings\<username>\Local Settings\Application Data\Microsoft\Silverlight\OutOfBrowser\<appid>
AppId is generated at runtime which includes some random number along with domain name so for example, if you are browsing it on a localhost, AppId could be something like “2748978495.localhost”.
How does OutOfBrowser Silverlight 3 App Work?
1. Silverlight 3 runtime installs “sllauncher.exe” to launch a silverlight xap package, on my machine it is installed at <system drive>:\Program Files\Microsoft Silverlight\sllauncher.exe
2. When you install Silverlight App as OOB, it downloads the xap package at isolated storage
3. Silverlight runtime creates a “metadata” and generate “index.html” file to host the silverlight control at isolated storage
4. When you click on shortcut or start-> to launch Silverlight app, it has a command line target to launch “sllauncher.exe <appid>”, appid is nothing but the isolated storage folder name
5. sllauncher is a win32 app which loads silverlight plugin(npctrl.dll) along with IEFrame.dll to host silverlight
6. Isolated storage also includes “index.html” which hosts the silverlight xap package, “sllauncher.exe” loads IEFrame to host html/silverlight control using browser host service
Below is the snapshot of isolated storage when you install silverlight application as out of browser
What does metadata contain?
Silverlight metadata for out of browser application as shown below can be directly edited in a hex editor(unicoded string , not a binary file) or a notepad
You can open it using any text editor, no need of using hex editor.
I have quickly put together a wpf app with bunch of controls slapped in to read/modify silverlight oob metadata, click to download along with source form here to view/modify metadata
Below is the snapshot of Silveright Out of browser application modified metadata
You can pretty much modify everything in metadata.
Can I modify metadata or run out of browser silverlight xap package without downloading it?
Absolutey, Out of Browser is not really out of browser because you do need a host to host silverlight xap package so Silverlight Team did a clever implementation to load html file using SLLAUNCHER.exe and of course sllauncher uses the same infrastructure as real browser does by loading silverlight plugin(npctrl.dll-com dll) to bootstrap silverlight core clr.
Steps to create your own out of browser silverlight app to host any xap package without downloading/installing it from silverlight app on internet
1. click to download SLMetaData along with source to view/modify metadata , it also includes a zip file with metadata,xap and html which you can unzip to execute sllauncher.exe
2. launch slmetadata.exe and click on File->Open to open “metadata”
3. Modify any of the field you want and click on to save the metadata
4. Create “index.html” file and specify the xap package path as shown below
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head>
<style type=’text/css’>
html, body { height: 100%; overflow: auto; }
body { padding: 0; margin: 0; }
#silverlightControlHost { height: 100%; }
</style>
</head>
<body scroll=”no” onload=”document.getElementById(’_sl’).focus()”>
<div id=”silverlightControlHost”>
<object id=’_sl’ data=”data:application/x-silverlight,” type=”application/x-silverlight” width=”100%” height=”100%”>
<param name=”source” value=”D:/SilverlightOOB/application.xap”/>
<param name=”background” value=”White”/>
<param name=”enableGPUAcceleration” value=”False”/>
<a href=”http://go.microsoft.com/fwlink/?LinkID=124807″ style=”text-decoration: none;”>
<img src=”http://go.microsoft.com/fwlink/?LinkId=108181″ alt=”Get Microsoft Silverlight” style=”border-style: none”/>
</a>
</object>
<iframe style=’visibility:hidden;height:0;width:0;border:0px’></iframe>
</div>
</body>
</html>
5. Make sure that the path to the “index.html” file is same as specified under the LaunchPath in metadata
6. Make sure that the name of the metadata file is “metadata” and is copied at the same location as your html file
7. Execute the following command “sllauncher.exe <folder path to html file>”, make sure sllaucnher.exe is in your path
8. you can also download the complete zip package to try it out by executing the above command
for example -”sllauncher.exe D:\SilverlightOOB”
That’s all, Silverlight OOB is possible with the help of loader which gets installed along with silverlight 3 runtime which does use IEFrame so not really out of browser
but out of browser indeed
Below is the snapshot of html, folder path and command prompt

FolderPath Snapshot

Command Prompt Snapshot

How to Revert back & forth between Silverlight 3 runtime and Silverlight 2 runtime - Ensuring That Your Silverlight 2 Applications Work with Silverlight 3
July 12th, 2009With the release of Silverlight 3, you may run into issue where silverlight 2 application may not work as expected. Please read this article on msdn Ensuring That Your Silverlight 2 Applications Work with Silverlight 3
You may need to revert to Silverlight 2 runtime to make sure that the issue has to do with the Silverlight 3 runtime. First of all in order for you to revert back and forth between Silverlight 2 and Silverlight 3 runtime, you should not uninstall Silverlight 2 runtime from your machine. Silverlight runtime gets loaded based on Silverlight plug in which is a COM dll(npctrl.dll).
COM Dll CLSID is “DFEAF541-F3E1-4c24-ACAC-99C30715084A” which remains same in silverlight 3 basically, you can’t run Silverlight 2 and Silverlight 3 runtime(CLR for Silverlight) side by side. Once you install Silverlight 3 runtime, browser running silverlight 2 app will load the Silverlight 3 runtime, you can verify that by looking at the loaded silverlight runtime dll in browser process space. By Default, Silverlight 3 will be installed in “C:\Program Files\Microsoft Silverlight\3.xxxx” so in order for you to revert back and forth all you need to do is register and unregister com dll.
You can simply create a batch file to do the job
for example
Batch file to revert to silverlight 2 runtime, click to download
regsvr32 /u /s “C:\Program Files\Microsoft Silverlight\3.0.40624.0\npctrl.dll”
regsvr32 /s “C:\Program Files\Microsoft Silverlight\2.0.40115.0\npctrl.dll”
Revert to silverlight 3 runtime, click to download
regsvr32 /u /s “C:\Program Files\Microsoft Silverlight\2.0.40115.0\npctrl.dll”
regsvr32 /s “C:\Program Files\Microsoft Silverlight\3.0.40624.0\npctrl.dll”
interesting windows service hang issue because of zone identifier data
July 11th, 2009The first time I came across this issue, my ex-boss Bill Vieux pointed it out immediately when we were looking at hang dump. I came across this issue again last week so I thought I will blog about it, just in case anyone finds it useful.
Scenario:
Windows Service is configured to watch a folder to export a file, when a file is written to disk it will launch an executable with parameters. First of all, yes it is always a bad idea to launch an exe from a windows service but anyways, sometime you don’t have a choice. Windows service was hanging with the release of new executable and we could never recreate this issue. We asked for hang dump and the following is what we found on a callstack.
0:012> ~6kb
ChildEBP RetAddr Args to Child
00e8d07c 7e419418 7e42770a 00000000 00000000 ntdll!KiFastSystemCallRet
00e8d0b4 7e4249c4 003d060c 00000000 00000001 USER32!NtUserWaitMessage+0xc
00e8d0dc 7e424a06 03850000 03ab83f8 00000000 USER32!InternalDialogBox+0xd0
00e8d0fc 7e4247ea 03850000 03ab83f8 00000000 USER32!DialogBoxIndirectParamAorW+0×37
00e8d120 77fa9ef1 03850000 00001140 00000000 USER32!DialogBoxParamW+0×3f
00e8d188 7e2f3dc1 03850000 00001140 00000000 SHDOCVW!SHFusionDialogBoxParam+0×3a
00e8d1a8 7e2f43b4 00000000 00001140 00e8d1fc SHDOCVW!_ShowSafeOpenDialog+0×26
00e8f6d0 7ca4d2ec 00000000 0019400c 00194008 SHDOCVW!SafeOpenPromptForShellExec+0×2ce
00e8f6f0 7ca04173 0019400c 00000001 00194008 shell32!CShellExecute::_ZoneCheckFile+0×60
00e8f708 7ca040fa 0019400c 013ca5c0 00194008 shell32!CShellExecute::_VerifyZoneTrust+0×2a
00e8f72c 7ca03071 0019400c 00e8fa0c 00194008 shell32!CShellExecute::_VerifyExecTrust+0xa4
00e8f754 7ca02f6a 013ca5c0 00190f00 00e8fa0c shell32!ShellExecuteNormal+0×30
00e8f770 00a3b0aa 013ca5c0 11ad3aad 00000000 shell32!ShellExecuteExW+0×8d
If you are familiar with alternate data stream, you will notice VerifyZoneTrust immediately. When we dump the parameter passed in internaldialogbox, below is what we have
0:012> dc 03ab83f8 03ab83f8 + 512
03ab83f8 80c80ac0 00000000 00000011 01090000 …………….
03ab8408 000000a9 00000000 004d0008 00200053 ……….M.S. .
03ab8418 00680053 006c0065 0020006c 006c0044 S.h.e.l.l. .D.l.
03ab8428 00000067 50000080 00000000 000a000a g……P……..
03ab8438 001400f5 ffff1141 00440082 0020006f ….A…..D.o. .
03ab8448 006f0079 00200075 00610077 0074006e y.o.u. .w.a.n.t.
03ab8458 00740020 0020006f 0070006f 006e0065 .t.o. .o.p.e.n.
03ab8468 00740020 00690068 00200073 00690066 .t.h.i.s. .f.i.
03ab8478 0065006c 0000003f 00000000 50000003 l.e.?……….P
03ab86f8 0069004c 006b006e 00540000 00690068 L.i.n.k…T.h.i.
03ab8708 00200073 00790074 00650070 006f0020 s. .t.y.p.e. .o.
03ab8718 00200066 00690066 0065006c 00630020 f. .f.i.l.e. .c.
03ab8728 006e0061 00680020 00720061 0020006d a.n. .h.a.r.m. .
03ab8738 006f0079 00720075 00630020 006d006f y.o.u.r. .c.o.m.
03ab8748 00750070 00650074 002e0072 004f0020 p.u.t.e.r… .O.
03ab8758 006c006e 00200079 00750072 0020006e n.l.y. .r.u.n. .
03ab8768 006f0073 00740066 00610077 00650072 s.o.f.t.w.a.r.e.
03ab8778 00660020 006f0072 0020006d 00750070 .f.r.o.m. .p.u.
03ab8788 006c0062 00730069 00650068 00730072 b.l.i.s.h.e.r.s.
03ab8798 00790020 0075006f 00740020 00750072 .y.o.u. .t.r.u.
03ab87a8 00740073 0020002e 0041003c 0048003e s.t… .<.A.>.H.
03ab87b8 0077006f 00630020 006e0061 00490020 o.w. .c.a.n. .I.
03ab87c8 00640020 00630065 00640069 00200065 .d.e.c.i.d.e. .
03ab87d8 00680077 00740061 00730020 0066006f w.h.a.t. .s.o.f.
03ab87e8 00770074 00720061 00200065 006f0074 t.w.a.r.e. .t.o.
03ab87f8 00740020 00750072 00740073 003c003f .t.r.u.s.t.?.<.
03ab8808 0041002f 0000003e 00000000 00000000 /.A.>………..
03ab8818 80c80ac0 00000000 00000011 01090000 …………….
03ab8828 000000a7 00000000 004d0008 00200053 ……….M.S. .
03ab8838 00680053 006c0065 0020006c 006c0044 S.h.e.l.l. .D.l.
03ab8848 00000067 50000080 00000000 000a000a g……P……..
03ab8858 001400f5 ffff1141 00440082 0020006f ….A…..D.o. .
03ab8868 006f0079 00200075 00610077 0074006e y.o.u. .w.a.n.t.
03ab8878 00740020 0020006f 0070006f 006e0065 .t.o. .o.p.e.n.
03ab8888 00740020 00690068 00200073 00690066 .t.h.i.s. .f.i.
03ab8898 0065006c 0000003f 00000000 50000003 l.e.?……….P
We have a modal dialog box with message “Do you want to …, file can harm your computer…” and since windows service is not running in interactive desktop mode, you are not going to see the warning message.
on executing streams( downloadable from http://technet.microsoft.com/en-us/sysinternals/bb897440.aspx) on exe, we see the following output
D:\Tools\Streams>streams “d:\xxxxx.exe”
Streams v1.56 - Enumerate alternate NTFS data streams
Copyright (C) 1999-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
:Zone.Identifier:$DATA 26
Zone.identifier is added as a security measure to every executable when downloaded from http or on a network share.
Since this application could be deployed using xcopy, so someone unzipped on a network share to copy the executable and of course windows service is now hung. Although, it is always a bad idea to launch exe but sometime there is no option so watch out for this scenario
Writing a dynamic, configurable windows service with better debugging experience
July 9th, 2009I was writing a media streaming service along with file watcher so I thought I will share this piece of code in case anyone finds it useful. When developing Win32 Windows NT Service in old days, it used to be an exercise to debug a windows service from visual studio, I will always end up in writing a test harness to test those dependent dlls.
Although, managed code has made our life easier but I still write a service with nothing in it other than service control manager startup.
Step 1 - Define a contract for dynamic and configurable service
public interface IDynamicService
{
void StartUp(NameValueCollection configData);
void Shutdown();
}
Step2 - Service is configurable from a config file
<configuration>
<configSections>
<sectionGroup name=”StreamingServices”>
<section name=”ServiceMap” type=”System.Configuration.NameValueSectionHandler” />
<!– List of services–>
<section name=”MediaService” type=”System.Configuration.NameValueSectionHandler” />
<section name=”MaintenanceService” type=”System.Configuration.NameValueSectionHandler” />
</sectionGroup>
</configSections>
<appSettings>
<add key=”AppName” value=”StreamingServices” />
<add key=”ServiceName” value=”MediaService” />
</appSettings>
<StreamingServices>
<ServiceMap>
<!–Start MediaService only–>
<add key=”MediaService” value=”TRUE” />
</ServiceMap>
<MediaService>
<!– type name implementing the service–>
<add key=”Type” value=”StreamingMedia” />
<!– assembly name implementing the type, assembly metadata table only contains the assembly name with path or extension–>
<add key=”AssemblyName” value=”MediaService” />
<!–path to the assembly–>
<add key=”AssemblyPath” value=”MediaService.dll” />
<!–this service watches the folders for filesystem events–>
<add key=”Folders” value=”D:\StreamingService\Host” />
</MediaService>
<MaintenanceService>
<add key=”Type” value=”MaintenanceService” />
<add key=”AssemblyName” value=”MaintenanceService” />
<add key=”AssemblyPath” value=”MaintenanceService.dll” />
</MaintenanceService>
</StreamingServices>
</configuration>
Step 3 - create a struct for serviceinstance metadata
struct ServiceInstance
{
public NameValueCollection Configuration { get; set; }
public IDynamicService DynamicServiceInstance { get; set; }
}
Step 4 - Implementing the dynamic service
/// <summary>
///
/// </summary>
/// <param name=”appName”></param>
public DynamicService(string appName)
{
//read the service map section to iterate through list of services
NameValueCollection serviceMap = ConfigurationManager.GetSection(appName + “/ServiceMap”)
as NameValueCollection;
foreach (string serviceName in serviceMap.Keys)
{
try
{
//if the service name is true in the config file, add it to the list
//<add key=”MediaService” value=”TRUE” />
if (Convert.ToBoolean(serviceMap[serviceName]))
{
ServiceInstance serviceInstance = new ServiceInstance();
serviceInstance.Configuration = ConfigurationManager.GetSection(appName + “/” + serviceName)
as NameValueCollection;
serviceList.Add(serviceInstance);
}
}
catch (Exception ex)
{
//log it
throw ex;
}
}
}
public bool Start()
{
//iterate through each service set to true in config file
//<add key=”MediaService” value=”TRUE” />
for (int i = 0; i < serviceList.Count; i++)
{
try
{
ServiceInstance serviceInstance = serviceList[i];
//try to load the service using reflection
serviceInstance.DynamicServiceInstance = LoadServices(serviceInstance.Configuration);
if (serviceInstance.DynamicServiceInstance != null)
//service implementing the contract IDynamicService will be started here
serviceInstance.DynamicServiceInstance.StartUp(serviceInstance.Configuration);
}
catch (Exception ex)
{
//log it
throw ex;
}
}
return true;
}
/// <summary>
/// Shutdown all the services
/// </summary>
public void Shutdown()
{
//shutting down services in reverse order
for (int i = serviceList.Count - 1; i >= 0; i–)
{
try
{
ServiceInstance serviceInstance = serviceList[i];
if (serviceInstance.DynamicServiceInstance != null)
serviceInstance.DynamicServiceInstance.Shutdown();
}
catch (Exception ex)
{
//log it first
throw ex;
}
}
}
/// <summary>
/// this method is called recursively, it first loads the assembly as configured in .config
/// and then loads the type
/// </summary>
/// <param name=”assemblyPath”></param>
/// <param name=”typeName”></param>
/// <param name=”assemblyName”></param>
/// <returns></returns>
private object LoadType(string assemblyPath, string typeName, string assemblyName)
{
object objInstance = null;
bool assemblyLoaded = false;
try
{
//iterate through each assembly in the current domain to compare it with the
//configured assembly in app.config
Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
//if assembly name is defined in the config file, load the type
//<add key=”AssemblyName” value=”MediaService” />
if (assembly.GetName().Name == assemblyName)
{
assemblyLoaded = true;
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.Name == typeName)
{
//<add key=”Type” value=”StreamingMedia” />
//if type name is defined, create the instance
objInstance = assembly.CreateInstance(type.FullName, false);
assemblyLoaded = true;
break;
}
}
break;
}
}
//called to load assembly from path
if (assemblyLoaded == false)
{
//<add key=”AssemblyPath” value=”MediaService.dll” />
Assembly.LoadFrom(assemblyPath);
//recursive call here
objInstance = LoadType(assemblyPath, typeName, assemblyName);
}
}
catch (Exception ex)
{
//log message
throw ex;
}
return objInstance;
}
/// <summary>
/// read the config section to load the assembly and type
/// </summary>
/// <param name=”configData”></param>
/// <returns></returns>
private IDynamicService LoadServices(NameValueCollection configData)
{
IDynamicService objRet = null;
try
{
string assemblyPath = configData[ASSEMBLY_PATH];
string typeName = configData[TYPE_NAME];
string assemblyName = configData[ASSEMBLY_NAME];
objRet = LoadType(assemblyPath, typeName, assemblyName) as IDynamicService;
}
catch (Exception ex)
{
//log message
throw ex;
}
return objRet;
}
}
Step 5 - Since we are going to watch the file system, we should never process a file in the same thread as the filewatcher event handler(cause of missing events, blocking the thread for longer duration, buffer and etc), we should just follow a producer consumer model to queue the data and hand it over to consumer. we will create a generic thread safe queue first
public class SyncQueue<T>
{
#region Private variables
private const int DEFAULT_CAPACITY = 25;
private object _syncRoot = null;
private Queue<T> _syncQueue = null;
private AutoResetEvent _resetEvent = new AutoResetEvent(false);
#endregion
#region Constructor
public SyncQueue()
: this(DEFAULT_CAPACITY)
{
}
public SyncQueue(int capacity)
{
_syncQueue = new Queue<T>(capacity);
_syncRoot = ((ICollection)_syncQueue).SyncRoot;
}
#endregion
#region public methods
public void Enqueue(T data)
{
if (data == null) new ArgumentNullException(”Null Argument”);
lock (_syncRoot)
{
_syncQueue.Enqueue(data);
}
_resetEvent.Set();
}
public T Dequeue()
{
lock (_syncRoot)
{
return _syncQueue.Dequeue();
}
}
public AutoResetEvent Signal
{
get { return _resetEvent; }
}
public int Count
{
get { return _syncQueue.Count; }
}
public Queue<T> Queue
{
get { return _syncQueue; }
}
#endregion
}
Step 6 - now we will define an abstract base class for File System Events, I have the FileSystemWatcher created in this base class to handle events but it may be better to have a composite type with filters and FileSystemWatcher created in a derived class for better reusability but it serves the purpose for me. I still prefer to suffix it with “Base” which is not preferred by many for abstract class
public abstract class FileSystemWatcherBase
{
#region Properties
private SyncQueue<string> FileQueue { get; set; }
private string RootPath { get; set; }
private string[] Filters { get; set; }
#endregion
#region constructors
protected FileSystemWatcherBase() { }
public void Initialize(FSStruct fsData)
{
CheckForNullArguments(fsData.FileQueue, “DataQueue<string> fileQueue”);
CheckForNullArguments(fsData.RootPath, “string rootPath”);
CheckForNullArguments(fsData.Filters, “string[] filters”);
FileQueue = fsData.FileQueue;
RootPath = fsData.RootPath;
Filters = fsData.Filters;
}
#endregion
#region public members
public virtual void Start()
{
string[] folders = Directory.GetDirectories(RootPath);
foreach (string folder in folders)
{
foreach (string filter in Filters)
{
CreateFSWatcher(folder, filter);
}
}
}
#endregion
#region protected members
protected void CreateFSWatcher(string folder, string filter)
{
FileSystemWatcher watcher = new FileSystemWatcher();
// Create a new FileSystemWatcher and set its properties.
watcher.Path = folder;
watcher.IncludeSubdirectories = true;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = filter;
// Add event handlers.
watcher.Created += new FileSystemEventHandler(OnCreated);
watcher.Error += new ErrorEventHandler(OnError);
// Begin watching.
watcher.EnableRaisingEvents = true;
}
#endregion
#region private methods
private void OnError(object source, ErrorEventArgs e)
{
Exception ex = e.GetException();
//to do—
}
private void OnCreated(object source, FileSystemEventArgs e)
{
FileQueue.Enqueue(e.FullPath);
}
private void CheckForNullArguments(object obj, string paramName)
{
if (obj == null)
throw new ArgumentNullException(paramName, “Null arguments in FileSystemWatcher Constructor”);
}
#endregion
}
#region data structure
public struct FSStruct
{
public SyncQueue<string> FileQueue;
public string RootPath;
public string[] Filters;
}
#endregion
Step 7 - Media Service to monitor and process the files
//implements the IDynamicService
public class MediaService : FileSystemWatcherBase, IDynamicService
{
private Thread workerThread;
private bool isRunning = false;
private SyncQueue<string> _fileQueue;
private AutoResetEvent _waitEvent;
public MediaService() { }
public void StartUp(NameValueCollection configData)
{
_waitEvent = new AutoResetEvent(false);
_fileQueue = new SyncQueue<string>();
string[] filters = { “*.mp4″, “*.mpeg” };
FSStruct fsData = new FSStruct()
{
FileQueue = _fileQueue,
Filters = filters,
RootPath = configData["Folders"]
};
Initialize(fsData);
Start();
}
public override void Start()
{
isRunning = true;
workerThread = new Thread(new ThreadStart(Run));
workerThread.Start();
_waitEvent.WaitOne();
Thread.Sleep(100);
base.Start();
}
public void Shutdown()
{
isRunning = false;
_fileQueue.Signal.Set();
ThreadHelper.WaitForThreadTermination(workerThread);
}
private void Run()
{
while (isRunning)
{
_waitEvent.Set();
_fileQueue.Signal.WaitOne(); // Wait for the file
while (_fileQueue.Count > 0)
{
try
{
//to do with file
}
catch (Exception ex)
{
//to do
}
}
}
}
}
Step 8 - Writing the service
Just 2 lines of code either in a console app or a Windows Service OnStart().
This will load numbers of services dynamically from a config file. Services can be removed or a new one can be added directly in a config file. You can debug it directly from a console appor a forms app making it reusable
protected override void OnStart(string[] args)
{
string appName = ConfigurationSettings.AppSettings["AppName"];
new DynamicService(appName).Start();
}
WinDbg meta-command tip to display all the extension commands exported by WinDbg extension
July 7th, 2009Usually, A WinDbg extension will have the !help command in case you need to look at the supported commands in an extension. However, not all commands may be documented or no documentation at all. In that case you can use Depends or any dissembler to look at the Export section.
But, with .extmatch command, you can achieve the same right in the debugger itself as shown below.
Below is the executed command to display all the extension commands supported by loaded SOS in CLR 4.0
remember the space between sos and *
0:020> .extmatch /D /e c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos *
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.AnalyzeOOM
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.BPMD
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.CLRStack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.COMState
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ClrStack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpArray
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpAssembly
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpClass
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpDomain
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpHeap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpIL
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpLog
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpMD
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpMT
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpModule
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpObj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpRuntimeTypes
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpSig
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpSigElem
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpStack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpStackObjects
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.DumpVC
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Dumplog
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Dumpruntimetypes
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.EEHeap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.EEStack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.EEVersion
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.EHInfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Ehinfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.FinalizeQueue
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.FindAppDomain
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.FindRoots
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Findappdomain
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCHandleLeaks
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCHandleleaks
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCHandles
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCHeapStat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCInfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCRoot
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GCWhere
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GcHeapStat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.GcWhere
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Gchandleleaks
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HandleCLRN
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HeapStat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Help
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistClear
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistInit
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistObj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistObjFind
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistRoot
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.HistStats
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.IP2MD
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ListNearObj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.MinidumpMode
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Minidumpmode
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Name2EE
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ObjSize
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.PrintException
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Printexception
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ProcInfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.RCWCleanupList
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Rcwcleanuplist
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.SOSFlush
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.SaveModule
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.StopOnException
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Stoponexception
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.SyncBlk
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ThreadPool
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ThreadState
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Threads
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Token2EE
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.TraverseHeap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Traverseheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.U
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.VMMap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.VMStat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.VerifyHeap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.VerifyObj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.VerifyStackTrace
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.Verifyheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.WatsonBuckets
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.analyzeoom
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ao
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.bpmd
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.clrstack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.comstate
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.da
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.do
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dso
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumparray
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpassembly
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpclass
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpdomain
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpil
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumplog
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpmd
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpmodule
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpmt
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpobj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpruntimetypes
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpsig
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpsigelem
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpstack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpstackobjects
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.dumpvc
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.eeheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.eestack
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.eeversion
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ehinfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.finalizequeue
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.findappdomain
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.findroots
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.fq
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gchandleleaks
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gchandles
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gcheapstat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gcinfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gcroot
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.gcwhere
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.heapstat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.help
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histclear
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histinit
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histobj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histobjfind
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histroot
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.histstats
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.hof
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.ip2md
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.listnearobj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.lno
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.minidumpmode
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.name2ee
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.objsize
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.pe
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.printexception
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.procinfo
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.rcwcleanuplist
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.savemodule
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.soe
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.sosflush
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.stoponexception
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.syncblk
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.t
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.threadpool
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.threads
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.threadstate
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.token2ee
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.tp
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.traverseheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.u
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.verifyheap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.verifyobj
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.vh
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.vmmap
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.vmstat
!c:\WINDOWS\Microsoft.NET\Framework\v4.0.20506\sos.vo