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

Posted on 2008-06-24
Medium Priority
Last Modified: 2010-04-01

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 ?
Question by:thordk
LVL 86

Expert Comment

ID: 21862044
#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")

Author Comment

ID: 21862350
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 ?
LVL 86

Expert Comment

ID: 21862544
>>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.
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

LVL 86

Expert Comment

ID: 21862557
... that is, I have no clue at the moment  either ;o)

Author Comment

ID: 21862559
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 ?
LVL 86

Expert Comment

ID: 21862645
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)
LVL 53

Assisted Solution

Infinity08 earned 400 total points
ID: 21863920
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.

Assisted Solution

bdunz19 earned 400 total points
ID: 21864318
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,
LVL 46

Assisted Solution

by:Kent Olsen
Kent Olsen earned 400 total points
ID: 21865085
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,
LVL 39

Accepted Solution

itsmeandnobodyelse earned 800 total points
ID: 21892352
>>>> All good advise here.  :)


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


Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

599 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