Sign in to follow this  
sandy

Writing a log entry before crashing?

Recommended Posts

I'm setting up a better logging system than the one I have now, which was just a plain text file. The new system uses XML in a similar fashion to the article about this here on GameDev. Anyway, the problem is that the XML file needs to be terminated with a </SystemLog> tag, otherwise when I try to load the XML file in say internet explorer I receive an error. If the program runs fine from start to finish, no problem as I can just write the terminating </SystemLog> tag to the end of the XML file when the program closes. However, if the program crashes, then it terminates without shutting down the logging system, which means the </SystemLog> tag is not written to the XML file. Is there some way that I can ensure that this </SystemLog> tag will be written to the end of my log file no matter how the application is terminated?

Share this post


Link to post
Share on other sites
Create file with closing tag.

When you want to write to the log. Move the file pointer back the number of character that the closing tag takes. Then write log text and closing tag.

Then when there is a crash the closing log is there. Unless the crash takes place during the log writing.

Share this post


Link to post
Share on other sites
I considered the following methods when I had this problem:

  • Write the SytemLog end tag out every time you add an entry, then seek the file back to overwrite it with the next entry
  • Don't write out the SystemLog tags at all - associate a program that writes them then opens the file in IE/Firefox/whatever to the extension you use for your logs
  • Monitor you main program with an external process which writes the tag on exit

Share this post


Link to post
Share on other sites
In addition to try/catch, iirc you need to use __try / __except / __finally to handle windows-generated exceptions (such as writing to a an invalid memory location). Of course, they're an MSVC extension to C++ and I don't know the equivalents for other compilers.

Share this post


Link to post
Share on other sites
You can't rely on exceptions for this - none of them will work if your code manages to blue-screen-of-death your PC.

On the other hand, it may just be easier to manually edit the log file in the event of a crash causing a BSOD, since they're very rare.

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
In my opinion, XML is the wrong choice for a logging format. As you've managed to discover, it does not cope well with sudden termination - which is one of the main times you'd want to look at a log.


QFE.

Share this post


Link to post
Share on other sites
Quote:
Original post by dawidjoubert
rather keep a log of the last 10 important operations that occured, then keep over writing the old one. This can give you some idea of where the crash occured(in a worst case scenario).


What would that solve? You would still need a closing tag on a BSOD if you use a format needing a closing tag.

Share this post


Link to post
Share on other sites
I uses a RTF text document for my log. Backing up over the ending tag every time isnt that much of an issue.
Only thing that is a real issue is remembering to fflush after every write, so unless it dies in your logging code,
there is always the last completed log writen to disk.

Share this post


Link to post
Share on other sites
This might be a complex system, but I think it would be robust:

I would write out a starting and closing tag to start with, then scan back to the inside of it. Subsequently, only write start tags if you can follow them with closing tags. I didn't read the gamedev XML article, I'm only familiar with XML.

Another thing to take a look at is std::atexit(). It sets a function to call when a program terminates. I don't know if it would still work on a crash. If it's a soft Windows crash, maybe. Prob not a BSOD.

Share this post


Link to post
Share on other sites
Wow guys! Thanks for all the replies!

Anyway, I really like the idea of always writing the closing tag since it is just a single line. Then, when I write the next log entry, I'll just write over the closing tag and write it again after the log entry.

The only question I have left now, is what would be the easiest way to write over the last line in the file. I'm happy to use either a file HANDLE or a std::ofstream for my reading/writing. However I would probably prefer the file HANDLE so I don't have to rely on STL. But if it is easier with STL, then I'll use that.

Any suggestions would be great.

Share this post


Link to post
Share on other sites
xml is very good for a logger it lets u prune the data
anyways i have the same issue
the solution (from memory though i couldnt get it working, its not high on the TODO list )
is to have 2 xml files the logged entrys are contained in one
thus it doesnt have <SystemLog></SystemLog>
+ the other file contains
<SystemLog>
body = see other file
</SystemLog>

thus it doesnt matter if it crashs

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
Quote:
Original post by zedzeek
xml is very good for a logger it lets u prune the data


A straw man argument. Pruning the data neither deals with the problem of abrupt termination, nor is it a feature unique to XML.


Although data pruning and sorting isn't unique to XML, there are a lot of existing free tools for working with XML which makes it an excellent choice if you can solve the abrupt termination problem (which can be done by several methods so far pointed out in this thread).

Share this post


Link to post
Share on other sites

the best way to ensure that you have written to a file, just before a crash, is to flush the cache to the hard disk.

to do this, you open the Log file with fopen(yourfilename,"wc"); , the "c" in the second parameter allows you to call the fflush(yourfilehandle) command, which inmediately sends the cached data to the hard disk.

So, you just call fflush(yourfilehandle) just after every log write.

Notice that fflush will not return until the data has been physically written to the hard disk, this means that the logging process will be extremely slow. Personally, I have two versions of the log, one without the fflush, and another, just for critical operations, with the fflush, placed just before crash prone code.

Share this post


Link to post
Share on other sites
If you need it for debugging on your own system i have another suggestion:

Use a log host app. I've got a debug host, that's started up on my PC per default. Now the game/app to be debugged calls a log function that uses WM_COPYDATA to send a string or hex data to that app. Whatever my app does, crash or something else, the log information is available in the debug host.

No need to search for a log file somewhere which needs to be deleted.

Of course this doesn't work with a BSOD, but seriously, i wasn't able to generate a BSOD on XP ever.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this