Solved

Windows Service unexpectedly terminates

Posted on 2009-05-13
14
3,606 Views
Last Modified: 2012-05-06
I have written a Windows XP Windows Service with Visual Studio 2005 in C# that terminates unexpectedly from an access violation after about 10-20 minutes.  When I run the same exact code as a Windows application it can run for hours (I terminated it after 17 hours) without a problem.  The service has account type LocalSystem, Manual startup type, uses TCP/IP listener and client sockets in asynchronous manner.  It also uses ADO and ADOX to update and write data to an Access database.

The first thing I did was search EE and the net for solutions, but didn't find any that seemed to apply to my problem.
 
I put log file writing and try catch blocks everywhere in an attempt to narrow down the culprit.  The problem seemed to be occuring in-between timer Elapsed events, so I got rid of the timer and used a thread with a loop that calls Thread.Sleep(15000).  The Thread.Sleep() call is inside of a try/catch block.  The Elapsed event handler is where the service does all of its processing.  It didn't help.  I bracketed the sleep call with some log file writing and confirmed that the access violation was occurring during the call to Thread.Sleep().

TheWindows Event Viewer had this info after termination:
Source: ".NET Runtime 2.0 Error Reporting"
Category: "None"
Type: "Error"
Event ID: "1000"
Description:  "Faulting application myservice.exe, version 1.0.0.0, stamp 497e0848, faulting module unknown, version 0.0.0.0, stamp 00000000, debug? 0, fault address 0x4de76542."

After this I ran "sc query myservice" from a command prompt and got:
TYPE:                            110 WIN32_OWN_PROCESS (interactive)
STATE:                          1 STOPPED (NOT_STOPPABLE, NOT_PAUSABLE,IGNORES_SHUTDOWN)
WIN32_EXIT_CODE:     1067 (0x42B)
SERVICE_EXIT_CODE:   0 (0x0)
CHECKPOINT:                0x0
WAIT_HINT:                   0x0

I then ran "net helpmsg 1067" from a command prompt and got:
"The process terminated unexpectedly."

 I have downloaded the latest updates from Microsoft for the .NET Framework, but the problem still occurs.  I attached the service's process to Visual Studio for debugging, but when the AV occurs, it doesn't give any faulting module information, it just asks if I want the application to handle the exception, which it apparently can't.

I attached the service process to OllyDbg for debugging, but I am not very familiar with that app yet and didn't know what I should be looking for/at.  When the AV occurred, it also wanted me to pass the unhandled exception back to the service app.

I really want this code to run as a Service and not a Windows app.  Any suggestions?
0
Comment
Question by:Chuck Yetter
14 Comments
 
LVL 9

Expert Comment

by:BlueYonder
ID: 24378940
Could you also attach the logs from the event viewer.
0
 
LVL 16

Expert Comment

by:JohnBPrice
ID: 24379188
My guess is that you are sleeping on the main service thread and that Windows when it checks that you are still alive is not getting a response, and thus kills your service.

You are starting a new thread in the OnStart event?
0
 
LVL 2

Expert Comment

by:phead_2
ID: 24380138
Can you provide a code example? You really should be able to catch the exception and log it or during debugging, it would be helpful to see what you're actually trying to do.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24384979
"Could you also attach the logs from the event viewer."

From the Application Events log:
5/14/2009      8:01:17 AM      .NET Runtime 2.0 Error Reporting      Error      None      1000      N/A      COMPUTER_1      Faulting application myservice.exe, version 1.0.0.0, stamp 4a0c12ba, faulting module unknown, version 0.0.0.0, stamp 00000000, debug? 0, fault address 0x4de76542.
5/14/2009      7:48:16 AM      MyService           Information      None      0      N/A      COMPUTER_1      Service started successfully.

From the System Events log:
5/14/2009      8:01:28 AM      Service Control Manager      Error      None      7034      N/A      COMPUTER_1      The MyService service terminated unexpectedly.  It has done this 1 time(s).
5/14/2009      7:48:16 AM      Service Control Manager      Information      None      7036      N/A      COMPUTER_1      The MyService service entered the running state.
5/14/2009      7:48:16 AM      Service Control Manager      Information      None      7035      DOMAIN_NAME\COMPUTER_1      COMPUTER_1      The MyService service was successfully sent a start control.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24385025
"My guess is that you are sleeping on the main service thread and that Windows when it checks that you are still alive is not getting a response, and thus kills your service.

You are starting a new thread in the OnStart event?"

Yes I was initially starting the timer when the OnStart event ended, then I got rid of the timer and spawned a thread in the OnStart event instead and used Sleep() in the thread.  I tried reducing the sleep time from 15 sec. to 2 sec. to 1 sec. to .5 sec to zero (commented out the call to Thread.Sleep()) and the service still terminated unexpectedly.
0
 
LVL 21

Expert Comment

by:mastoo
ID: 24385480
Yes, after starting the timer you need to return from OnStart (get rid of the sleep).  But that won't cause the error you are getting - it would log an event that says the service failed to start.  Are you doing any unsafe/unmanaged code or using 3rd party products?  If not, I'd have faith in the visual studio debugger.  Use a debug build and set the option to break on handled and unhandled exceptions and then look at the call stack when it breaks.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24387264
All code is C#, with no 3rd party products.  

Ran the debug version of service and attached process to Visual Studio.  Here is the call stack that popped up when the exception occurred.  It doesn't really tell me anything, but it might mean something to someone who knows what they are looking at.

>      kernel32.dll!RaiseException()  + 0x52 bytes      
       [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]      
       mscorwks.dll!79f63db7()       
       mscorwks.dll!79e8d193()       
       mscorwks.dll!79f64192()       
       mscorlib.ni.dll!792e25b5()       
       mscorlib.ni.dll!792e2576()       
       mscorlib.ni.dll!792dec1d()       
       mscorwks.dll!79e885a2()       
       mscorwks.dll!79eb448c()       
       System.ni.dll!7a94ab1e()       
       mscorwks.dll!79e813ec()       
       mscorwks.dll!79e813ec()       
       mscorlib.ni.dll!792d6d66()       
       mscorlib.ni.dll!792e01ef()       
       mscorlib.ni.dll!792d6ce4()       
       mscorwks.dll!79e71b4c()       
       mscorwks.dll!79e821f9()       
       mscorwks.dll!79e9605b()       
       mscorwks.dll!79e96571()       
       mscorwks.dll!79e7e9a4()       
       mscorwks.dll!79e96920()       
       mscorwks.dll!79e964ae()       
       mscorwks.dll!79e964be()       
       mscorwks.dll!79e7a1d2()       
       ntdll.dll!RtlAllocateHeap()  + 0x15e bytes      
       mscorwks.dll!79e7a1d2()       
       mscorwks.dll!79e7a1f1()       
       mscorwks.dll!79e7a17a()       
       mscorwks.dll!79e7ffe4()       
       mscorwks.dll!79e965a4()       
       mscorwks.dll!79e965c2()       
       mscorwks.dll!79f3d883()       
       ntdll.dll!wcsncpy()  + 0xb07 bytes      
       ntdll.dll!RtlAllocateHeap()  + 0x117 bytes      
       mscorwks.dll!79e7a1d2()       
       ntdll.dll!RtlAllocateHeap()  + 0x15e bytes      
       mscorwks.dll!79e7a1d2()       
       mscorwks.dll!79e7a1f1()       
       mscorwks.dll!79e7a17a()       
       mscorwks.dll!79e984cf()       
       mscorwks.dll!79e9846b()       
       mscorwks.dll!79e79cea()       
       mscorwks.dll!79e79cfd()       
       mscorwks.dll!79eecefa()       
       mscorwks.dll!79e98391()       
       mscorwks.dll!79e9851d()       
       mscorwks.dll!79f3d654()       
       mscorwks.dll!79f3d72e()       
       mscorwks.dll!79e7a1d2()       
       mscorwks.dll!79f920a5()       
       mscorwks.dll!79e964ae()       
       mscorwks.dll!79f92093()       
       kernel32.dll!GetModuleFileNameA()  + 0x1ba bytes      

 
Here are the contents of the thread window:
      4320      Win32 Thread      KiFastSystemCallRet      Normal      0
       6108      Win32 Thread      KiFastSystemCallRet      Normal      0
       5788      Win32 Thread      KiFastSystemCallRet      Highest      0
       2840      Win32 Thread      KiFastSystemCallRet      Normal      0
       8088      Win32 Thread      KiFastSystemCallRet      Normal      0
       4284      Win32 Thread      KiFastSystemCallRet      Normal      0
       4852      Win32 Thread      KiFastSystemCallRet      Normal      0
       336      Win32 Thread      KiFastSystemCallRet      Normal      0
       2896      Win32 Thread      KiFastSystemCallRet      Normal      0
>      4588      Win32 Thread      RaiseException                      Normal      0
       5492      Win32 Thread      KiFastSystemCallRet      Normal      0
       6184      Win32 Thread      KiFastSystemCallRet      Normal      0
       6172      Win32 Thread      KiFastSystemCallRet      Normal      0
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24387309
After I pass the unhandled exception back to the application I get this call stack:

>      4de76542()      
       user32.dll!GetDC()  + 0x6d bytes      
       [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]      
       user32.dll!GetDC()  + 0x14f bytes      
       user32.dll!GetWindowLongW()  + 0x127 bytes      
       user32.dll!DispatchMessageW()  + 0xf bytes      
       ole32.dll!CoFreeUnusedLibrariesEx()  + 0x23d bytes      
       ole32.dll!CoGetObject()  + 0x1843 bytes      
       ole32.dll!CoGetObject()  + 0x1776 bytes      
       ole32.dll!StringFromGUID2()  + 0x5dc bytes      
       kernel32.dll!GetModuleFileNameA()  + 0x1ba bytes      

and this list of threads:

       4320      Win32 Thread      KiFastSystemCallRet      Normal      0
       6108      Win32 Thread      KiFastSystemCallRet      Normal      0
       5788      Win32 Thread      KiFastSystemCallRet      Highest      0
       2840      Win32 Thread      79e7da12                      Normal      0
       8088      Win32 Thread      79e717df                                      Normal      0
       4284      Win32 Thread      InterlockedDecrement      Normal      0
>      4852      Win32 Thread      4de76542                      Normal      0
       336      Win32 Thread      KiFastSystemCallRet      Normal      0
       2896      Win32 Thread      71a515f6                                      Normal      0
       4588      Win32 Thread      RaiseException                      Normal      0
       5492      Win32 Thread      KiFastSystemCallRet      Normal      0
       6184      Win32 Thread      RtlEnterCriticalSection      Normal      0
       6172      Win32 Thread      79e72132                      Normal      0
0
 
LVL 21

Expert Comment

by:mastoo
ID: 24387472
ooooh, yes I'm not going to be much help other than to agree it looks like a .net framework problem.  I notice GetDC on the stack which seems like an odd call to be happening in a non-gui service.  You aren't using any forms or gui stuff in your application are you?  Otherwise the only thing that comes to mind would be try building with the framework 3 or 3.5 to see if the problem magically goes awya.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24387573
Yes, I thought GetDC() seemed out of place as well.  

I am using several System.Windows.Forms.BindingSource objects as part of my database interaction, even though they aren't connected to a form.  I'll do a build minus the binding sources and see what happens.  

As far as I know, VS2005 only uses .NET 2.0.  
0
 
LVL 21

Accepted Solution

by:
mastoo earned 500 total points
ID: 24387614
My oversight - you are right about .net 2.0
And that is a good idea to remove the binding source.  Ideally you wouldn't have System.Windows.Forms as a reference in a app that runs as a service.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24396021
I removed the System.Windows.Forms reference, and the Binding Source  related code, but the service still terminated.  So then I removed the adodb and ADOX references as well, commented-out all related code, re-built, and all was fine.  I let it run overnight and it had no problems.  

I suspected it might be the ADOX reference that was causing the problem so I re-built with only the ADOX reference removed and related code commented-out, and it has been running smoothly for almost an hour and a half now.  ADOX can be used to get at certain Access database properties that adodb can't, and it's not a typical reference which is why I suspected it first.  I only needed ADOX for validating and updating the database, so I'll have to work around that.

Soo... the moral to the story seems to be "Don't use a reference to the ADOX dll in a Windows Service".

Thanks, mastoo, for getting me moving in the right direction on this one.  
0
 
LVL 21

Expert Comment

by:mastoo
ID: 24396973
Interesting.  I hadn't even noticed adox.  That's com you're using through interop?  If so, we can speculate it either doesn't handle threading properly or it might be using a hidden window for the old com marshalling.  But either way, glad you were able to resolve it.
0
 
LVL 6

Author Comment

by:Chuck Yetter
ID: 24397157
You wouldn't have noticed adox (Interop.ADOX.dll) because it didn't show up on the call stack printouts.  The adox code is only called at service startup.  Why it should crash the service 5-15 minutes later is a mystery to me.  
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now