service crashing on close - can allocated/not freed memory cause it ?

Hello,

Got an application running as service, and has done for ages - it has one problem, whenever i close it, it will crash because i didnt do the proper cleanup/synchronization when i made it.

Im in the process now of fixing this, it looks nasty in the eventlog, and now im regretting i didnt do it proper from start.

My first question is - lets say ive got alot of allocated memory that isnt freed in the end, even though it should be freed, wouldnt it just get rid of itself when the process dies ? it wouldnt cause by itself a crash would it ?

Second question is more codelike; one of the issues i have is that i initiate "kill" events to the threads ive launched, but i dont know when they actually quits, so i send the END, and then let the process die, and guess that is wrong.

How would you normally do this sync and wait for all threads to finish gracefully ?
thordkAsked:
Who is Participating?
 
itsmeandnobodyelseConnect With a Mentor Commented:
>>>> All good advise here.  :)

Yes.

To add to above comments:

In order to get a short response from your threads when sending the kill events, each thread must check for the kill event after each major operation. It is best you put the check into a little function so that it easily can be called by your threads:


bool Thread::isTerminated()
{
       // wait 1 millisecond
       unsigned int ret = WaitForSingleObject(myKillEvent, 1);  
       return (ret != WAIT_TIMEOUT);
}

void threadFunc(void * ptr)
{
       Thread* pThis = (Thread*) ptr;
       
       while (!pThis->isTerminated() )
       {
               if (!pThis->doWhatMustBeDone()) break;

       }
 
}

bool Thread::doWhatMustBeDone()
{
        ...
        for (...)
        {
             // call as often as possible especially in lengthy operations
             if (isTerminated()) return false;
             ....
        }
         return true;
}

Regards, Alex

0
 
jkrCommented:
#i'd suggest to run the service as a simple user mode app for debugging purposes. If you cannot reproduce the problem that way, see http://msdn.microsoft.com/en-us/library/ms682546(VS.85).aspx ("Debugging a Service")
0
 
thordkAuthor Commented:
Jkr you are starting to be my guarding angel here.

But i know of several situation that would cause a crash, there are thread-interactivity, where one thread might be destroying an instance that the other one is trying to reach so there are several situations i know it would go wrong.

But i wonder if just allocating memory, and not deallocating it again can be a reason for a crash ? it shouldnt be should it ? at least there should be some code-execution that will cause the error am i right ?
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jkrCommented:
>>But i wonder if just allocating memory, and not deallocating it again can be a
>>reason for a crash ?

At first glance, I'd say "no" - but you never know what turns out to be the real source of your problem. It might sound archaic, but debugging the process in question has always proven to me to be the best way to carry on. Once you excluded a certain issue, it is nice to see how much you can narrow a problem down. So far, your description to broad for me to recommend anything specific.
0
 
jkrCommented:
... that is, I have no clue at the moment  either ;o)
0
 
thordkAuthor Commented:
Okay get your point.

Just wanted to narrow my work - goal is in the first place just to get it not-puking when stopping, if i can achieve that by fixing codeproblems (ex. syncs) and not thinking of making sure everything is deallocated too then it would make it alot less work i think.

Can i keep this one open for a while, if i have an additional question in my search ?
0
 
jkrCommented:
Sure, keep it open and feel free to add any details you might get known to in the mean time. BTW, a stack trace would be a nice start, I'd even go for a DrWatson log ;o)
0
 
Infinity08Connect With a Mentor Commented:
To answer your questions

>> My first question is - lets say ive got alot of allocated memory that isnt freed in the end, even though it should be freed, wouldnt it just get rid of itself when the process dies ?

When the process ends, the operating system reclaims the memory. So all un-freed memory will still be reclaimed by the OS.
However, it is still a good idea to do all the cleaning yourself, to end the process properly, but more importantly to run the code in the destructors, which might do more than just free memory. It might liberate resources, close connections, close files, etc.

Note that most of these will be done by the OS too when the application ends, but not necessarily in the proper way (order etc. might be important, or something more might need to be done).

So, I always recommend to properly clean everything in order to have a clean shutdown.


>> it wouldnt cause by itself a crash would it ?

That depends. If you have a lot of memory being used by the application (and never freed) for example, you might run out of memory ... Which can (eventually) cause the application to crash if not handled correctly.


>> Second question is more codelike; one of the issues i have is that i initiate "kill" events to the threads ive launched, but i dont know when they actually quits, so i send the END, and then let the process die, and guess that is wrong.

Again, it's a good idea to properly close down your threads. Ie. send them a message to indicate that they should stop whatever they're doing (so they can do that properly), and then end themselves. In the main thread, you can then simply have a thread join, and wait until all threads have shut down by themselves.
0
 
bdunz19Connect With a Mentor Commented:
Hi, in response you your codelike issue:

When you recieve SERVICE_CONTROL_SHUTDOWN or SERVICE_CONTROL_STOP, what you are doing will work, by signaling  a kill event. Then next step you need to do is (hopefully you are keeping track of your thread handles) wait for your threads to exit. When you create a thread it returns a handle, which you can use to detect when the thread has exited. So run some WaitForSingleObject()s or WaitForMultipleObjects()s to wait for your threads to finish up. Then make sure to CloseHandle() the thread handles.

When you say you send an END, do you mean something like ExitProcess()? To give a better idea of how this would work, I will describe how I have structured my services in the past. In my WinMain or entry point function I would do all the service initilization followed by launching my main threads. Then my WinMain would wait infinitly on the kill event that I had created. When the service control handler receives either of those stop messages, I then signal my kill event. This causes not only the threads to exit but also lets my WinMain continue on past that WaitForSingleObject(hKillEvent, INFINITE). Once it pases that wait, it then would wait on all the threads to finish and exit cleanly with a nice "return 0;" from WinMain.

Hope that helps,
Brandon
0
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
Hi thordk,

All good advise here.  :)

One other thing to be aware of is freeing the same memory twice.  This will certainly cause a crash.  And there are numerous ways to fall into this.

  TClassA   *ClassAObject = new TClassA;   //  Create an object.
  SomeAPI->Add (ClassAObject);                 //  Pass it to another object to be added to it.

Now, who owns the memory that contains the object?  Some classes will create a copy of the data so that the calling routine (what you see above) needs to delete the object.  Other classes will simply keep a pointer to the object and expect to Add the actual item so an explicit delete is wrong.

You may well be in a situation where a class destructor is deleting an object that is being deleted by another class's destructor.

When you explicitly delete (or free) an object, it's generally a good idea to put NULL into the pointer.  That way if the cleanup operation attempts to delete (or free) it again, the operation will gracefully NOT try to delete (free) the object a second time.


Good Luck,
Kent
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.