NPS
NPS

Reputation: 6355

How to protect log from application crash?

I've created a simple logger which, well, logs everything of importance into a text file. I'm using std::ofstream but there's a problem - when the program doesn't close the file (call std::ofstream::close()) for whatever reason (like crash), the created log is actually empty (0 size). And since the log is most useful in exceptional situations (when something goes wrong) - you see the problem.

Is there any way to protect my log from that? I could try closing the file after writing every couple of lines and using append - but that still doesn't protect me from the situation when the program crashes in the middle of logging/before closing the file. Is there any solution or am I just doomed?

Upvotes: 5

Views: 2921

Answers (2)

MSalters
MSalters

Reputation: 179981

In our commercial application, we had a very robust solution for that. The price was non-portability.

We installed a Vectored Exception Handler. This handler is called in case of an unhandled OS exception, before the program exits (which is by far the most common crash). When it's called, you can not call C++ Standard Library function anymore (or even C functions). Even fflush is unreliable.

Yet it is OK to call basic OS functions. Be careful, though. Setting up the arguments for the OS call shouldn't use malloc either. Have the name of the crashfile already set up before the crash actually happens, etc. Do close the file immediately, again using OS functions.

Upvotes: 2

Alexander Shukaev
Alexander Shukaev

Reputation: 17021

You should employ flush method, it is there to precisely solve problems like the one you're facing.

There is another approach which can be considered more safe, but requires substantially more effort to implement and test. The approach boils down to what is known as inter-process communication (IPC). In brief, you could implement your logger as a separate logger application which would communicate with your target application by means of specific protocol (interface). You can develop such protocol by yourself or employ one of the existing ones (which are usually very generic, i.e. general purpose). As a result, if your target application crashes, it doesn't drag logger application with it, and therefore logger can safely finish its job.

That approach is usually used by some huge, complex, and safety-critical systems. However, I guess that in your case this is definitely an overkill and bare flush() after each append is more than enough.

Upvotes: 4

Related Questions