Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

Breaking Up (shared services) Is(n't) Hard To Do

Breaking Up (shared services) Is(n't) Hard To Do

  • Comments 19
The last time I wrote, I talked about shared services. One of the problems of working with shared services is that sometimes one service in the process gets in the way of other services.

For the audio service, it lives in the "networking services" service host (because the networking services svchost is used for all services that run as LocalSystem).  But, because it runs in the same process as the networking functionality, it means that it can be quite difficult to debug the audio service, especially if you're using a source level debugger - if your debugger has to talk to the network, and portions of the networking stack are suspended (by the debugger) it can be hard to make things work...

It turns out that there's a remarkably clever trick that can be used to split a normally shared service into its own process. 

From a Windows command prompt, simply type:

C:\>sc config <servicename> type= own

To move the service back into its normal shared config, type:

C:\>sc config <servicename> type= share

The SC tool should be in the system32 directory on all XP installations, if not, it's in the platform SDK (I believe), and obviously you need to be an administrator to make this work.

I can't take credit for this, it was shown to me by one of the NT perf guys, but I like it sufficiently that it's worth sharing.

 

One more caveat: Before people start trying this on their XP system, please note that there's a reason that those services are in the same process.  Splitting them up will cause your system to use a LOT more memory, and WILL make your system unstable.  I'm posting this trick because it can be quite useful for people who are developing their own shared services.

Several of the built-in services assume that they're in the same address space as other services, and if they start running in separate processes, they will crash in strange and mysterious ways, if you're not careful, you can render your machine unbootable.

Just don't go there, it wouldn't be prudent.

  • You shouldn't encourage modding and tweaking as it will just give added ammo to the open source zealots who think information is better when it is free/Free.
  • Rot, I actually thought about that, that's why the big caveat about you breaking your system if you attempt to do this to a Windows system.

    And the info's already out there, it's not like people like Mark Russinovitch etc don't already know this stuff.
  • Larry,

    is this trick something special that sc.exe knows about the svchost interface or does it apply generally to arbitrary services created with SERVICE_WIN32_SHARE_PROCESS as the dwServiceType parameter of CreateService? In other words: Will it bypass whatever I specified in CreateService and affect the SCM's service start strategy which you described in your previous essay? If this is the case and if it isn't something svchost-related, what API does this command invoke to achieve that? Does it just call CreateService again for the service in question but this time forcing SERVICE_WIN32_OWN_PROCESS?

    Just curious,

    --
    S
  • Stefan, sc.exe is a command line wrapper around the service control APIs. All it's doing is calling ChangeServiceConfig to change the service start type.

  • Larry,

    Do you know the consequences of trying to configure a normally separate service as a shared service? i.e. Should this be relatively safe:

    sc config iPodService type= share

    ?
  • Do the NT perf folks know of a good way to determine which service is running away with memory in a sahred process? I suppose there could be a way to determine it with the Kernel Debugging tools etc? Is there some windbg incantation that could tell me that?
  • Shivram, there are ways to do it, but they're not trivial.
  • >> Several of the built-in services assume that they're in the same address space as other services

    this sounds a bit scarey. is this a legacy issue or was the decision to create such interdependence explicitly made? and why? ps. i've never written a service so it may be that the answer is implicit.
  • I note that my installation of Exchange Server 2000 Enterprise runs no fewer than nine services, ALL of which run as LocalSystem.

    I think this is a good thing.

    If one blows up, the other eight have a shot at continuing to run. So if the SMTP service dies, people can still retrieve their mail via MAPI, IMAP, and POP3.
  • [quote]
    if you're not careful, you can render your machine unbootable.
    [/quote]
    So that means the command to move the service out of svchost is permenent. Is that correct?

    If so, it may be much better if there's a switch to seperate it temporately. Then the service will run in the normal way if the test fails.
  • Speaking (writing?) as a tester, breaking services into their own processes is often a good thing. Run those nasty stress tests against the service, turn on app verifier, do really nasty horrible things - and only affect the service you're testing.
    Another time this counts (and I wish we had "official" internal builds with services broken out by default to test this) is when one service in the process starts scribbling over another's memory in some way that the devs can't figure out. Granted, most of those head-scratching cases come in the form of Watson reports, so it's too late to apply the (mostly) one service per process model, but I honestly think we'd catch most of the offenders (earlier and with almost zero additional dev/test work) if we had a "split services" build that testers were required to run agiainst. Picture it as something like we have pseudo-localized builds today - they're not the kind of thing we really want to ship to customers but they make some otherwise difficult-to-find problems immediately obvious.

    I'd really hate to add even more "process" overhead though. IMHO we already have enough of that and we've passed some tipping point: I think we're erring on the side of "better" quality and creating sluggish development cycles, so I can't take a really strong stand about my opinions above. I can really only require breaking out the service I personally work on.
  • I notice that sc.exe interacts with the console using the Console APIs. This makes it unusable in other contexts, such as the RXVT terminal that comes with Cygwin. These other contexts expect a simple redirected pipe to be able to communicate with command-line programs.

    For example, just running sc asks 'Would you like to see help for the QUERY and QUERYEX commands? [ y | n ]:'. Try tying this in under cmd.exe:

    echo n | sc

    It still asks: it doesn't read from the redirected pipe, even under cmd.exe.

    This is extremely poor behaviour for a command that people can resonably expect to be able to script.

    It would be great if all command-line programs with XP only used standard C-style I/O with the console. It seems that some at Microsoft have a habit of using GUI idioms (such as the dialog above that ignores previously stuffed input) in the wrong place (i.e. the command line).

    All this to basically say: I can't use SC on a day to day basis. I can use cygrunsrv for simple tasks like installing, uninstalling, starting and stopping services.
  • <blockquote>Several of the built-in services assume that they're in the same address space as other services...</blockquote>

    Umm... why? Shouldn't these be fixed to either be a single service, or use real APIs to call each-other's functionality? I understand that the second may kill performance, but the first should be fairly easy, no?

    It seems to me that this is just /asking/ for trouble, like the bad old days of windows 3.1 applications modifing each-other's USER resources.
  • Dan/James, as the author of one of the dependencies (the browser and server service), some of it's for performance reasons (the server calls into the browser for some remoted APIs, and by making the two depend on each other, I acheived a significant perf enhancement for the network neighborhood).

    Cheong, the process of moving the service out-of-proc isn't permanant. But you might have to boot in safe mode to repair the damage.

    barrkel, I'll ask the service controller guys if they know what's up with that. SC's a pretty old tool though...
  • > as the author of one of the dependencies
    > (the browser and server service), some of
    > it's for performance reasons (the server
    > calls into the browser for some remoted APIs,

    Hmm. Does that have any connection with the following observation:

    If I open Windows Explorer, navigate to My Network, and drill down to the workgroup name that was set during installation of all the Windows machines involved, the machine whose shared folder I want to access is not shown. But if I right-click the My Network icon and search for the machine I want to access, then right-click the machine's icon and choose Explore, then the new instance of Windows Explorer shows the machine in a workgroup called UNKNOWN. I can access its shared folder at that point. Of course on the other machine itself, it still knows that its real workgroup name is the same as everyone else's.

    Maybe someone else took over your code after your significant perf enhancement? Maybe they didn't notice all the places where the two services have to inform each other that something has changed in the information that they're supposed to be maintaining? Maybe breaking up would yield significant reliability enhancements?

    (This isn't 100% reproducible but in some configurations it's like 95% reproducible. It might be more reproducible in a case where one is running a checked build and one is running a retail build, both XP SP2.)
Page 1 of 2 (19 items) 12