Friday, April 18, 2008

Troubleshooting tip for troubled SVCHOST process

Understanding svchost.exe can be useful to help narrow down bugs in Windows services. No doubt you've noticed svchost.exe process instances running in task manager; there are usually 5-7 of them.

The proper name for svchost is the "Generic Host Process for Win32 Services". It's role is to be the host process for dll-based Windows services. So when you see multiple instances of svchost.exe running in your task manager, those processes are actually wrappers for services that are coded into DLL's.

There is not a 1-to-1 relationship between an svchost instance and a service. You can use the tasklist command (or Process Explorer if you prefer SysInternals tools) to see which services are running under any given process. A useful command to find all svchost.exe processes and their associated services is:

C:\>tasklist /svc /fi "imagename eq svchost.exe"

Image Name PID Services
========================= ====== =============================================

svchost.exe 1528 DcomLaunch, TermService
svchost.exe 1580 RpcSs

svchost.exe 1892 AudioSrv, BITS, CryptSvc, Dhcp, dmserver,
EventSystem, lanmanserver, lanmanworkstation,
Netman, Nla, RasMan, Schedule, seclogon, SENS,
SharedAccess, ShellHWDetection, srservice,
TapiSrv, Themes, TrkWks, W32Time, winmgmt,
wscsvc, wuauserv, WZCSVC
svchost.exe 1004 Dnscache
svchost.exe 1160 LmHosts, RemoteRegistry, WebClient
svchost.exe 876 BthServ

Your output will vary slightly, but you will get a good idea about how many services run against each svchost process instance. If you need to expand the service short names (as above) into long names, you can use the sc command. For instance, I don't know what the service BthServ is. Getting scared!

C:\>sc GetDisplayName BthServ
[SC] GetServiceDisplayName SUCCESS Name = Bluetooth Support Service

That sounds legit enough for me :).

So in their design of the Windows operating system, Microsoft decided to group different services into different processes. Why?

Reason 1: At one extreme, Microsoft could have decided to put all services into one process. However if some error were to happen in one service (such as an unhandled exception or access violation) the whole process (all services) would crash. Were you ever told not to put all your eggs in one basket?


Reason 2: The other extreme would be to put each service in it's own process. Well if that were the case I would have another 27 processes on my system. If you have ever studied kernel design you will understand that less processes means less context switches required to keep the system responsive. It's just more efficient to have less processes and more threads. If you find this at all interesting, I highly recommend a book called Operating System: Internals and design principals by William Stallings.


Reason 3: Limiting of the use of permissions. Services are run under different accounts so that they do not inherit privilages they do not need.


I'm sure there are other rationales for why the services are grouped the way they are, but I see those as the big ones.

Now the reason it is important to know how the Service host works is that without knowing it's purpose, it is impossible to debug! There are a few different problems I've had with SVCHOST. Well, actually that's not quite true. I've never had a problem with SVCHOST, it's always been the services running under the svchost process that has been causing problems.

Whenever I've had to debug issues relating to the svchost, it's often resulted in a need to "split" it's roles into other instances. I'm not going to go into the various issues I've had with the svchost, but if you Google svchost 100% CPU , you may find one or two search results on the matter. What I will discuss for you is the technique used to "split" the svchost.

So as I've mentioned, the svchost process hosts one or more services. The standard instances that ship with Windows has a particular configuration that Microsoft are happy with. If you need to, for troubleshooting purposes, pull one or more services into their own host process, here is how you would go about doing that. Lets say the offending service is the WMI service (Windows Management Instrumentation)...


1. Find the short name for the Windows Management Instrumentation service


2. Locate the service in the registry. In this case: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winmgmt\

3. Observe the current SVCHOST group the service is in by looking at the ImagePath key in the aforementioned registry section. You will see something like "%systemroot%\system32\svchost.exe -k netsvcs". So in this instance, the SVCHOST group is: netsvcs.

4. In this ImagePath key, change the netsvcs group to something different and unique. In this instance I will change it to split_wmi. That is the svchost group I'm chosing to create. Remember that case is critical.

5. Now locate the svchost configuration section of the registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost

6. In this registry section, you will find a Multi-string registry key for each svchost group that exists. So in this case you will find netsvcs. Open that up and take a look. You'll find something like this:




7. This key contains the list of service to start under the netsvcs SVCHOST instance. What we want to do is locate the winmgmt service name and remove that from the netsvcs group. Click OK once you've removed the line.

8. Next you'll need to create a new multi-string key called "split_wmi". This will create a new instance of the SVCHOST with that group name.

9. In the split_wmi key, insert just one line with the service name for the wmi service: winmgmt.

This procedure will become more natural once you've done it a few times. Thankfully you always backup your registry before you start tinkering! :)

I'm running a bit short for time, but if you need any advice tracking down this kind of bug, just leave a comment.

-M