How to debug Windows Services written in .NET? (part I)

Diagnosing Windows Services might sometimes be cumbersome – especially when errors occur during the service start. In this two-parts series I am going to show you different ways how to handle such problems in production. In the first part we will focus on “exceptions discovery” techniques which very often are enough to figure out why our service is not working. In the second part we will setup a debugging environment and attach a debugger to our service. Let’s start then.

Continue reading

Collect .NET applications traces with sysinternals tools

In this short post I would like to show you how, with sysinternals tools, you may noninvasively trace .NET applications. This is especially useful in production environment where you can’t install your favorite debugger and hang whole IIS to diagnose an issue. We will work with three tools: dbgview, procdump and procmon. Let’s start with the first one.

Continue reading

Reference Source, dotPeek and source code debugging

Not so long ago Microsoft has made .NET source code browsable through a really nice page: Additionally, they promised that the .NET Framework source code debugging will finally work in Visual Studio. At almost the same time JetBrains published EAP of its dotPeek tool with some great features that make “reverse-engineered debugging” extremely easy. And for other DLLs we still have the old Microsoft Public Symbols server. In this post I am going to show you how I configure my system and Visual Studio for different debugging scenarios.

Continue reading

Stopwatch vs. DateTime

.NET developers usually know they should measure code performance using a Stopwatch class from the System.Diagnostics namespace. From time to time though I see code where someone uses DateTime instances for this purpose. And it’s not very surprising as DateTime class is usually the one that comes to mind when you think of time in .NET. In today’s post I would like to show you the difference in accuracy of both those approaches and the price you need to pay using either of them. We will work on this sample code that does nothing but measure time :):

Continue reading

The truth about app_offline.htm

In this short post I would like to present you am interesting fact about app_offline.htm. Let’s start with a small puzzle. Imagine you have 2 files in your IIS application folder: web.config and app_offline.htm. Web.config contains following lines:

<?xml version="1.0"?>

and app_offline.htm:

We'll be back in a moment.

Notice that in the web.config file the configuration tag is not closed. Now the question is: what will you see if you try to access your application from the browser?

Continue reading

Injecting code into .NET applications

Recently I have been playing with Function Evaluation available in .NET debugging API. This functionality allows a managed debugger to inject some arbitrary code while the debuggee is stopped. The injected code might be simply a call to the object’s ToString method or to a property getter. As a developer you profit from this service when you use Watch windows or when you run some code in the Immediate window in Visual Studio. In this post I will present you my MDbg plugin (includes a command: inject) that adopts the funceval API and an example diagnostics case in which I used it.

Continue reading

Set process memory limit with Process Governor

Today I would like to introduce you to Process Governor – a new tool in my .NET diagnostics toolkit. This application allows you to set a limit on a memory committed by a process. On Windows committed memory is actually all private memory that the process uses. I wrote this tool to test my .NET applications (including web applications) for memory leaks. With it I can check if under heavy load they won’t throw OutOfMemoryException.

Continue reading

Find a performance counter instance by a process ID

Performance Counters are a great feature of Windows which allow you to monitor applications and the whole system in a noninvasive manner. Which makes them even better is a fact that you can gather the performance data remotely. You can find some more information on using Performance Counters in my previous post: Diagnosing applications using Performance Counters. When diagnosing a faulting application I usually start with IO, Memory and CPU metrics available in the Process counter. The Process counter has a separate instance for each process that is running on your machine. By default, instance names are composed of the process name they represent and some identifier (in case there are multiple processes with the same name), eg. w3wp, w3wp#1, w3wp#2. As I’m mostly working with web applications hosted in IIS I often ran into problem which counter instance represents an application pool I want to monitor. So I wrote a simple Powershell script that will find the counter by process id:

function GetPidsFromPerfCounter([string]$ComputerName, [string]$pcounter, [int]$ProcessId, [string]$f) {
  # dump counter values
  typeperf -f CSV "$ComputerName$pcounter" -sc 1 -o $f -y | Out-Null
  # import and parse the CSV file
  $t = import-csv $f -Delimiter ","
  $t.psobject.Properties | select -skip 1 | ? { 
    if ($ProcessId -ge 0) { $_.value -eq $ProcessId } else { $true }
  } | % { "{1,6} => {0}" -f $_.Name,$_.Value } | Sort-Object

function Find-ProcessCounterByPid(
  [Parameter(Mandatory=$False,ValueFromPipeline=$True)][int]$ProcessId = -1,
  [Parameter(Mandatory=$False,ValueFromPipeline=$False)][string]$ComputerName = $null,
  [Parameter(Mandatory=$False,ValueFromPipeline=$False)][switch]$IncludeDotNet = $False
) {
  if (-not [String]::IsNullOrEmpty($ComputerName) -and -not $ComputerName.StartsWith("\\")) {
      $ComputerName = "\\" + $ComputerName
  $f = [System.IO.Path]::GetTempFileName()
  # native counters
  GetPidsFromPerfCounter $ComputerName "\Process(*)\ID Process" $ProcessId $f
  # for .net counters we need to grap CLR Memory\ID Process
  if ($IncludeDotNet) {
    Write-Host "  ------- .NET PIDs ---------"
    GetPidsFromPerfCounter $ComputerName "\.NET CLR Memory(*)\Process ID" $ProcessId $f
  del $f

You might now wonder why I haven’t used the Get-Counter cmdlet. Unfortunately there is some bug in it and it does not print counter instance indexes (the part coming after # in the instance name) which, in our case, is a core requirement. You can paste the above code into your Powershell module and make the GetPidsFromPerfCounter private. Then you can call Find-ProcessCounterByPid with no arguments – in which case the cmdlet will print all available counter instances:

PS Diagnostics> Find-ProcessCounterByPid
     0 => \\PECET\Process(_Total)\ID Process
     0 => \\PECET\Process(Idle)\ID Process
     4 => \\PECET\Process(System)\ID Process
   280 => \\PECET\Process(smss)\ID Process
   396 => \\PECET\Process(csrss)\ID Process
   404 => \\PECET\Process(svchost#5)\ID Process
   456 => \\PECET\Process(wininit)\ID Process
   464 => \\PECET\Process(csrss#1)\ID Process
   532 => \\PECET\Process(winlogon)\ID Process
   548 => \\PECET\Process(services)\ID Process
   572 => \\PECET\Process(lsass)\ID Process
   576 => \\PECET\Process(nvxdsync)\ID Process
   664 => \\PECET\Process(svchost)\ID Process
   700 => \\PECET\Process(nvvsvc)\ID Process
   724 => \\PECET\Process(nvSCPAPISvr)\ID Process
   752 => \\PECET\Process(nvvsvc#1)\ID Process
   768 => \\PECET\Process(svchost#1)\ID Process
   796 => \\PECET\Process(SkyDrive)\ID Process
   820 => \\PECET\Process(svchost#2)\ID Process
   860 => \\PECET\Process(dwm)\ID Process
   896 => \\PECET\Process(svchost#3)\ID Process
   912 => \\PECET\Process(chrome#11)\ID Process
   964 => \\PECET\Process(svchost#4)\ID Process
  1008 => \\PECET\Process(vpnui)\ID Process
  1148 => \\PECET\Process(vmware-authd)\ID Process
  1204 => \\PECET\Process(vpnagent)\ID Process
  1236 => \\PECET\Process(svchost#6)\ID Process
  1244 => \\PECET\Process(googledrivesync)\ID Process
  1384 => \\PECET\Process(spoolsv)\ID Process
  1420 => \\PECET\Process(svchost#7)\ID Process

or specify a concrete PID:

PS Diagnostics> Find-ProcessCounterByPid 768
   768 => \\PECET\Process(svchost#1)\ID Process

Additionally, if you are also interested in profiling .NET Applications, add -IncludeDotNet switch that will list .NET counters instance indexes, eg.:

PS Diagnostics> Find-ProcessCounterByPid -IncludeDotNet 5824
  5824 => \\PECET\Process(powershell)\ID Process
  ------- .NET PIDs ---------
  5824 => \\PECET\.NET CLR Memory(powershell)\Process ID

By adding -ComputerName switch you may also collect performance data from a remote machine. I hope you will find the script useful. If you have any ideas how to improve it drop me a comment 🙂

MSBuild: MSB3275 warning, GAC and .NET version

UPDATE 2016-11-11: This issue seems to be fixed (checked on .NET 4.6.1586.0), and a valid version of GAC is used, depending on the framework version the application is using. I will keep the post for reference.

In this post I will describe for you an interesting problem that my colleague ran into at work. His original VS solution consisted of two projects targeting .NET 3.5 – let’s name them Alpha and Beta. Alpha had a direct reference to Beta and thus depended on it. Beta was using NHibernate, Castle.Core and some other libraries. During compilation Alpha he received:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1360,9): warning MSB3258: The primary reference "PathToBeta.dll" could not be resolved because it has an indirect dependency  on the .NET Framework assembly "mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "" than the version "" in the current target framework.

and the whole build failed with:

Error 3 The name 'Beta' does not exist in the current context

Continue reading

Introducing Musketeer – the performance counter data collector

In this post I will show you how to create a very simple Windows Service (I will call it Musketeer) that will collect information about other processes running on a server. Such a tool might be helpful if you host Windows services on some remote server and you want to store information about their performance in a database for further analysis. This tool might also be a cure if your admins didn’t give you enough privileges to connect the Performance Monitor to the remote server:)

Continue reading