The Description field in the properties of svchost.exe is “Host Process for Windows Services”, and it was created to reduce the number of processes running on the system to have a smaller load on system resources.
On my Windows 8 x64 machine there are 182 services visible through “View Local Services”, 101 of which have their status as “Running”, but as I type there are only 41* processes currently running in session 0, as displayed on the Details tab in Task Manager, which are potentially** background service processes.
* This excludes “System” and “System Idle Process” and “System Interrupts” as they are fake placeholder processes
** I say “potentially” as a single service could spawn child processes, either permanent or temporary
So 101 services running in a maximum of 41 processes, how is this achieved?
By collecting services that require similar privileges/permissions together into a group so they share a security token and virtual address space.
The first process in a group that gets started will create and initialize the svchost.exe process, and all subsequent services in that group will cause modules to be loaded and threads to be created.
Similarly, the process will exist while there is at least 1 service in the running state in that group.
The Group name can be seen by adding the column in the Services tab in Task Manager.
So we can see the benefit of this, but it introduces a bit of complexity when it comes to diagnosing crashing/hanging/misbehaving services hosted in these svchost.exe instances.
The first challenge is to determine which of the instances a service runs in – this is easier than it used to be thanks to the PID column in the Services tab in Task Manager, it used to be a case of running something like the following at a Command Prompt to locate the service in question and getting the corresponding process ID:
tasklist /svc /fi "imagename eq svchost.exe"
As all of the services in a group share the same process, if any of their threads encounter an unhandled exception, the process will be terminated – affecting all of the hosted services.
This leads to the symptom of the event log reporting many services “terminated unexpectedly” at the same time.
Only 1 of the services caused the problem, but how to identify which one it was?
The first step would be to isolate all of the services into their own processes, then see which individual service continues to have a problem – this is done (for service “foo”) through an elevated Command Prompt with the command:
sc config foo type= own
(The space between “=” and “own” is vital – the command does not succeed if this is left out.)
The next time the service starts, it will now create its own svchost.exe instance, even without modifying the command line that starts the service.
To later restore the service to its original state, i.e. once troubleshooting is concluded, the command is:
sc config foo type= shared
Mitigation & Investigation
So by isolating all of the services in a group which is having a problem then restarting the machine, we can now observe the individual services and have the chance to attach a debugger or get a crash dump which does not have any other process’ modules or threads confusing matters.
Even if the service with the problem continues to crash, the impact at least is hopefully mitigated as the other services in the group continue to run – so long as they are not dependent on the crashing service.
As soon as the individual service has been identified, the others in the group can be put back into the shared state, leaving only the 1 isolated until its problem is resolved.
Occasionally, and rather annoyingly, the service stops encountering problems once it is isolated – then the decision has to be made if it is simpler to leave it in that configuration as it works, or to continue spending (potentially a lot of) time trying different combinations/numbers of hosted services to see if the trigger can be identified.