Solved

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

Posted on 2008-06-24
10
276 Views
Last Modified: 2010-04-01
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 ?
0
Comment
Question by:thordk
10 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
#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
 

Author Comment

by:thordk
Comment Utility
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
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>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
 
LVL 86

Expert Comment

by:jkr
Comment Utility
... that is, I have no clue at the moment  either ;o)
0
 

Author Comment

by:thordk
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 86

Expert Comment

by:jkr
Comment Utility
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
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 100 total points
Comment Utility
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
 
LVL 4

Assisted Solution

by:bdunz19
bdunz19 earned 100 total points
Comment Utility
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
 
LVL 45

Assisted Solution

by:Kdo
Kdo earned 100 total points
Comment Utility
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
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 200 total points
Comment Utility
>>>> 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

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
maze travler 6 47
C++ assignment question 7 127
How to programmatically differentiate between C and Java 10 175
White board coding practice 3 60
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

771 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

10 Experts available now in Live!

Get 1:1 Help Now