• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 303
  • Last Modified:

my service crashes sometimes

Hello,

I've written an service using visual studio 2008. It works fine most of the time.
But sometimes it stops. No error Message appears and I can start it again.

The software run on about 200 PCs and crashes about 1 a day. Never the same :-)
So I can not provoke it.

I found a routine to get unhandled exceptions, but with this I can only capture about 5% of the crashes.

I did not get where the software crashes.
I addedd a debug log, but all I found is a line with "Sleep(1000);".

Does somebody know a better way to get crash information.

Stefan
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
 
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo)
{
...
}

Open in new window

0
StefanKittel
Asked:
StefanKittel
  • 5
  • 5
  • 2
2 Solutions
 
DanRollinsCommented:
Not an answer, but something I've found useful:
You can set the Windows Service Manager to restart your Service whenever it crashes.  In my software, I've arranged things so that after a restart, it immediately resumes where it left off... the client piece (the software that uses the server) may never even notice the 2- to 10-second delay (were it not for the entry in the Event Log and the log the service generates)
0
 
StefanKittelAuthor Commented:
Hello,

I do this allready. So the user may not even knows that chrash. But I would like to have a crash-free-software. Until this bug is in it, it may appear in other ways.

I've seen software that show's an informationen when crashing: exception in filename.cpp on line 231. But I did not found out how to do this.

Stefan
0
 
DanRollinsCommented:
You might get more details about the crash if you distribute a Debug build of your service (at least to a few computers, at least on a trial/diagnostic basis).  
If you already have a loggin mechanism of some sort, then add more detailed output.  For instance:
[timetamp] Starting Inet connections to [URL]
[timetamp] Connection complete; data obtainef (12345 bytes)
[timetamp] Saving data to database
[timetamp] Error 08000456 saving data in function SaveDataToDatabase
... that sort of thing.
 
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
StefanKittelAuthor Commented:
Hello,

I added debug infos so "SetUnhandledExceptionFilter" might get a better result.
Although I removed all functions from "MyUnhandledExceptionFilter" that can might prevent it to save the minidump.

Such Log I had before and this leads only to "Sleep(1000);" and increased the log file size to 60mb per day :-)

We'll see. I come back to you after eastern when I got results.

Stefan
0
 
DanRollinsCommented:
>> Such Log I had before and this leads only to "Sleep(1000);" ....
That is a particularly useless  log entry.  The log should indicate when it occurred and the entries just above it should indicate what function was being performed at that time.
However, it is a specific string of characters, so that means you can search your source code for it.  That will yield one or more candidates -- places that the error might have occurred.  Surround each of those candidates with additional logging message calls; make sure the messages are specific and useful.  Then the next time the error occurs, you will have more information and you can focus on the part of your program that has the problem.
0
 
jkrCommented:
You can keep track of these crashes in a better way when you build your service with "create map file" enabled and use your exception handler to track these crashes and locate the functions they occur in- Consider e.g.

#include <windows.h>
#include <stddef.h>
#include <stdio.h>

LONG
WINAPI
ExceptionHandler(LPEXCEPTION_POINTERS pe) {

    char acModule[MAX_PATH];

    MEMORY_BASIC_INFORMATION mbi;
    HMODULE hMod;

    VirtualQuery (pe->ExceptionRecord->ExceptionAddress,&mbi,sizeof(mbi));

    ptrdiff_t RVA = (char*)pe->ExceptionRecord->ExceptionAddress - (char*)mbi.AllocationBase;

    hMod = (HMODULE) mbi.AllocationBase;

    GetModuleFileName(hMod,acModule,sizeof (acModule));

    printf( "Detected Exception in %s at RVA 0x%08X\n", acModule, RVA);

    return EXCEPTION_EXECUTE_HANDLER;
}

void FaultingFunction () {

    LONG* p = NULL;
    *p = 42;
}

void main(){

    SetUnhandledExceptionFilter (ExceptionHandler);
    FaultingFunction ();
}

(compiled with "cl rvaxcept.cpp /link /map")

which prints

Detected Exception in C:\tmp\cc\rvaxcept.exe at RVA 0x00001088

The map file is

rvaxcept

Timestamp is 44660958 (Sat May 13 18:29:12 2008)

Preferred load address is 00400000

Start         Length     Name                   Class
0001:00000000 00004938H .text                   CODE
[...]

 Address         Publics by Value              Rva+Base     Lib:Object

0001:00000000       _ExceptionHandler@4        00401000 f   rvaxcept.obj
0001:0000007a       _FaultingFunction          0040107a f   rvaxcept.obj
0001:00000092       _main                      00401092 f   rvaxcept.obj
0001:000000a7       _printf                    004010a7 f   LIBC:printf.obj
0001:000000d8       _mainCRTStartup            004010d8 f   LIBC:crt0.obj
0001:000001b7       __amsg_exit                004011b7 f   LIBC:crt0.obj
[...]

You can see the 'Rva+Base' column, base is given as 'Preferred load address is 00400000'

Add that to the faulting module RVA of 0x00001088 and you get 0x00401088, then look that up in the above (i.e. the 'nearest symbol' and you can see that it is 'FaultingFunction'

0001:0000007a       _FaultingFunction          0040107a f   rvaxcept.obj
0001:00000092       _main                      00401092 f   rvaxcept.obj

The address is between main and FaultingFunction, which starts before 0x00401088, the next function is main and starts later.
0
 
StefanKittelAuthor Commented:
@DanRollins
This is the sourcecode:

AddDebugInfo("C8");
Sleep(1000);
AddDebugInfo("C9");

And the last Entry in my log is C8. Because it can't crash at Sleep, so the program must crash somewhere else.

@jkr
I use such a thing (see my code above). My Problem is, that the service sometimes stops without a trace. No Debug file or something else.
Which can't be with "SetUnhandledExceptionFilte".

I'll try current with enabled debug symbols and because I can't provoke the error. I'll have to wait.

Stefan
0
 
StefanKittelAuthor Commented:
@jkr
How can I save the mapfile? So the user can send It to me

Stefan
0
 
jkrCommented:
You don't have the user send it to you, it is created when you compile your service and therefore remains at yout machine...
0
 
DanRollinsCommented:
Just put an:
   AddDebugInfo( text of the exception message rather than printf );
to your code so the customer can send you the debug log and it will contain the relevant address for use in idenfying the crash location.
=-=--=-=-=-=-=-=-==-
If the last log message is "C8" and the crash occurs during the Sleep(1000) then we can assume that some secondary thread (that does not log itself) is to blame.
Just a thought:
A full 1-second sleep delay is an eternity.  Your service is incapable ot handling Service Manager requests or window events etc.  during this interval.  In fact, the Service Manager (or an external monitoring program) might be closing your program because it thinks it is non-responsive.
Is it possible to rearrange the functionality so that you use a 100-ms sleep delay?  Depending upon your program, you might need to pump messages, also.
0
 
StefanKittelAuthor Commented:
Hello Dan,

I don't have any other threads running.
And the Service commands would add an entry to the log.

My service is waiting about 5 minutes between actions. The Only action that could come is a stop to the service. Thats why i uses 1 second.

I wait to return unused cpu power backup. Or don't I have to?
My routine is a while checking different times.

Stefan

		AddDebugInfo("ServiceLoop", DebugType_Position, "Debug C8");
 
		//Sleep 1 Second, but only when not quiting
		
		index = 0;
		while ((index < 100) & (m_QuitMainLoop == FALSE))
		{
//			Sleep(10);
			if (WaitForSingleObject( stopServiceEvent, 10) != WAIT_TIMEOUT)
				m_QuitMainLoop = TRUE;
 
			index++;
		}
 
		AddDebugInfo("ServiceLoop", DebugType_Position, "Debug C8b");

Open in new window

0
 
DanRollinsCommented:
There are other events, such as SERVICE_CONTROL_INTERROGATE that need to be handled.  I've not used the
   WaitForSingleObject( stopServiceEvent ....

style of handling, so I'm not sure if the sleep interval and possible non-responsiveness is a problem.  Like I said "just a thought."
0

Featured Post

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

  • 5
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now