• Advertisement
Sign in to follow this  

execute cleanup code, even if programm crashes [c++]

This topic is 3583 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everybody, how can I execute clean up code, even if my programm crashes? my logger class creates xml files, but if my application crashes, my xml file does not end properly and i have to write the endtags manually to view it right. Is there a way to shut down my logger class correct, even if my application crashes? what about a seperate thread, even if my main thread crashes, the other one could end normally right? or exception handling, but it would be somehow out of my skills at the moment to figure out that solution. that would be my solution, but i am not sure about exceptions int main() { //create logger //catch any exception //create everything else //run main loop //shutdown //if catched, shut logger down & end programm //shutdown logger }

Share this post


Link to post
Share on other sites
Advertisement
Nope. Not within the program itself anyway. You could have an external process monitoring the program (which would be aware of the log file), this process could re-open the file, scan it and close any xml tags that remain. You still aren't guaranteed good output though.

XML is a bad choice for logs (IMO).

XML is really designed as a data-interchange format. Logs are fine as line based text files (easy to grep). Line based logs also neatly avoid such problems (the last line might be bad, but its not a big deal). You could always write a conversion script that parses a line based text file and outputs XML for you, if you *really* want to.

Share this post


Link to post
Share on other sites
1) The cleanest way to avoid this is to write code that doesn't crash.

2) Most of your crashes will be attributed to un-caught exceptions; correctly catching and handling exceptions should alleviate most problem cases. Exception handling is part of the above point-1 in actual fact.

3) Certain crashes are unrecoverable for a single program and an external process that monitors you main program can niggle round these, although really it's a bit extreme to be doing that.

4) There are cases where both your main program and any externally monitoring process will both terminate prematurely, if someone whips your power cable out for example.

Proper exception handling suffices for most programs. If, for those rare cases not covered by exceptions, those missing XML tags are causing you grief then an additional sanity-checking proceduce could parse and correct the file when your program is next executed.

Share this post


Link to post
Share on other sites
Of course, trying to intercept any mechanism that will crash your program will depend largely on what operating system your program will be running on. On Windows, at a minimum, you'd want a SEH handler in your main function and you should probably also install a signal handler to catch things like SIGABRT.

Share this post


Link to post
Share on other sites
This by very definition isn't possible.

You'll need a separate application, and use remote logging.

Quote:
what about a seperate thread, even if my main thread crashes, the other one could end normally right


Threads = same application
Process = different applications

If application crashes, all threads go with it.

Quote:
or exception handling


Umbrellas work to keep you dry. But when Titanic is sinking, opening one won't help you much. Exceptions are like umbrellas. They do the job when appropriate.

Quote:
Is there a way to shut down my logger class correct, even if my application crashes?


There might actually be a compromise, but I don't know the details. You could attach some process shutdown hook on your application, that would get ran when your application process closes. That one could then scan the XML file and balance the tags.

But no, there's no clean solution.

Not even for virtual machines - in Java, an OutOfMemory error will crash the application in same way, so will a few others. Similar for C#, where you need to add unmanaged resources to the mix.

Share this post


Link to post
Share on other sites
that may does not fit right, but do i get performance penalities for exception handling ??

Share this post


Link to post
Share on other sites
Quote:
Original post by Ben091986
that may does not fit right, but do i get performance penalities for exception handling ??


It depends. While most exception implementations do incur a small speed decrease for each function called, the code required to manually handle errors and pass them through to calling functions also has a cost. Comparing it to not handling errors at all isn't really meaningful.

Because you posted in "For Beginners", I am going to go with "enabling exceptions isn't what is going to slow your program down". Choosing the optimal algorithm for the most frequently executed game logic is the best way to be efficient in both programmer time and CPU time.

If you don't know your frequencies ahead of time, you cannot make informed decisions on where to optimise. As such, disabling exception handling for such dubious reasons as performance is not a smart move. If and only if later profiling indicates that exceptions are your bottleneck, then you could consider disabling them.

Share this post


Link to post
Share on other sites
AFAIK you only take a real performance hit if an exception is thrown, which should be exceptional (hence the name [wink]) and therefore should not be a real problem.

To help you a bit, a code snippet. For more: search the net. Oh, when you're in an exception handler, remember something went very wrong before that was called. So, you cannot blindly trust memory allocations etc. to be successful.

int main() {
::SetUnhandledExceptionFilter(ExceptionHandler);
// your program
}

LONG ExceptionHandler(_EXCEPTION_POINTERS *exceptionInfo) {
if( justLetWindowsHandleTheCrash )
return EXCEPTION_CONTINUE_SEARCH;

g_log.Close();
// Maybe some call to MiniDumpWriteDump?
::MessageBox( "A fatal exception occurred. Goodbye" );
return EXCEPTION_EXECUTE_HANDLER;
}


Share this post


Link to post
Share on other sites
To do this perfectly, create a process that handles logging.

Your program sends inter process communication messages to the logging process.

The logging process notices when your process goes away, and cleans up the log file and makes it a valid file.

(In my experience, a simple XML format can help with logging: you can have multiple views of the log file that provide more or less general or specific information about a given phase. I'm not saying that it is easy, but it can be useful!)

Share this post


Link to post
Share on other sites
How about writing the end of the file early on, then using seek to insert new content into the file?

Though your program should under no circumstances be crashing in the first place.

Share this post


Link to post
Share on other sites
Exception handling costs are highly dependent on the compiler, operating system and the exception implementation. For example, gcc can use SJLJ or DWARF2 exception handling. SJLJ slows down all code that uses exception handling even if an exception isn't thrown, but makes exceptions relatively low cost. DWARF2 exceptions tend to have a very low cost if exceptions aren't thrown but when an exception is thrown, it's very expensive. MSVC uses SEH for exceptions which also tend to have a low cost if exceptions aren't thrown, but are relatively expensive when they are thrown.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Exception handling costs are highly dependent on the compiler, operating system and the exception implementation. For example, gcc can use SJLJ or DWARF2 exception handling. SJLJ slows down all code that uses exception handling even if an exception isn't thrown, but makes exceptions relatively low cost. DWARF2 exceptions tend to have a very low cost if exceptions aren't thrown but when an exception is thrown, it's very expensive. MSVC uses SEH for exceptions which also tend to have a low cost if exceptions aren't thrown, but are relatively expensive when they are thrown.


I honestly prefer it like that (fast code, slow exceptions). I mean, if you're using exceptions for passing data around your program, you're doing things wrong. If something trips up an exception, then things are already going to take longer than expected.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
This by very definition isn't possible...there's no clean solution. Not even for virtual machines

Well, there's Erlang. And certain other languages enjoy having constructs like unwind-protect.

Share this post


Link to post
Share on other sites
Quote:
Original post by gsg
Quote:
Original post by Antheus
This by very definition isn't possible...there's no clean solution. Not even for virtual machines

Well, there's Erlang. And certain other languages enjoy having constructs like unwind-protect.


Now I've never coded in Erland, but a brief Google shows unwind-protect to be somewhat similar to RAII in C++. That is, it allows you to define certain actions that should be performed when the stack is unwound.
Great, that's a start.
But it doesn't help if the stack isn't unwound. It doesn't help if I just open task manager, right click the process and kill it.

(Or if you get an access violation or other errors that aren't caught as C++ exceptions)

Share this post


Link to post
Share on other sites
Yeah, I don't know that you could expect to recover at all in catastrophic situations like power-off or the OS intefering with program execution.

Regarding RAII, I'm not a C++ guy and I'm not clear exactly what sort of functionality you can reasonably move into constructors/destructors to take advantage of the technique. Fixing up logs doesn't really strike me as the sort of code that would naturally belong there - but perhaps that's my naive understanding of C++.

Share this post


Link to post
Share on other sites
I'm pretty sure this should be possible, I think it would just be platform specific. For windows, look for the dbghelp library. The book "Game Coding Complete" by Mike McShaffry has some example code that uses this library to create a memory dump when an application crashes (under windows).

I think the only problem, aside from the platform dependent thing, would be that you wouldn't be able to guarantee that your logging code would be in a safe state, but I think that's just a fact of life when your program crashes.

Obviously take my post with a pinch of salt, because I've never tried doing anything like this.

Share this post


Link to post
Share on other sites
Not really. For any error handling system there exists some kind of malformed behavior that would invalidate the system. For example, if you install an SEH exception handler in a thread to write a stack dump in that thread, you could have a stack overflow and not have the stack space to perform the stack walk. If you run an extra thread to monitor and perform stack dumps on other threads in the process, the memory of that thread could be overwritten by a stray pointer. If you spawn a second process to monitor the original process, it's possible for that process to get closed by a malicious TerminateProcess() call.

The best you can do is decide how much effort you want to spend and what percentage of funky behavior you want to catch, and then code to that. You might be able to get 99.9% of crashes or 99.99999% or even 99.999999999999999%, but you'll never get 100%.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement