Game Development Community

ConsoleLogger bug

by Daan Broekhof · in Torque Game Engine · 11/24/2004 (12:52 pm) · 9 replies

While tinkering with the ConsoleLogger class I stumbled on a bug in it:
When using more then one ConsoleLogger, the logger writes double lines (or as many ConsoleLoggers as you have active) into the log file.

This error is the result of the console callback function getting registered multiple times ( Con::addConsumer( ConsoleLogger::logCallback ); ), instead of just once for all ConsoleLoggers.

A fix is to make the mInitialized member of the ConsoleLogger a static field:

consoleLogger.h:
private:
      bool mLogging;         ///< True if it is currently consuming and logging
      FileStream mStream;    ///< File stream this object writes to
      bool mInitalized;      ///< This is for use with the default constructor
      bool mAppend;          ///< If false, it will clear the file before logging to it.
      StringTableEntry mFilename;      ///< The file name to log to.
to
private:
      bool mLogging;             ///< True if it is currently consuming and logging
      FileStream mStream;        ///< File stream this object writes to
      static bool mInitalized;   ///< This is for use with the default constructor
      bool mAppend;              ///< If false, it will clear the file before logging to it.
      StringTableEntry mFilename;      ///< The file name to log to.

To initialize the static member of the object we need to add 'bool ConsoleLogger::mInitalized = false;' to consoleLogger.cc:
consoleLogger.cc:
#include "console/consoleLogger.h"
#include "console/consoleTypes.h"

Vector<ConsoleLogger *> ConsoleLogger::mActiveLoggers;
bool ConsoleLogger::mInitalized = false;

IMPLEMENT_CONOBJECT( ConsoleLogger );

And then altering the init() method of the ConsoleLogger to:
consoleLogger.cc:
bool ConsoleLogger::init() {
   if( mInitalized )
      return true;

   Con::addConsumer( ConsoleLogger::logCallback );
   mInitalized = true;

   return true;
}

For tidyness I moved the 'mFilename == NULL' check from the init() method to the attach() method :
consoleLogger.cc:
bool ConsoleLogger::attach() {

   // Check to see if this is intalized before using it
   if( !mInitalized ) {
      if( !init() ) {
to:
bool ConsoleLogger::attach() {

   if( mFilename == NULL )
   {
      Con::errorf( "ConsoleLogger failed to attach: no filename supplied." );
      return false;
   }

   // Check to see if this is intalized before using it
   if( !mInitalized ) {
      if( !init() ) {

There are also some other improvements which can be implemented, like removing the registered callback function from the Con::removeConsumer() when there are no ConsoleLoggers active anymore, but I'll keep it at a bugfix for now.

#1
08/03/2005 (10:34 am)
Bump... Ben this is still a bug in 1.4 RC1. You can see it in action if you call writeOutFunctions() then call writeOutClasses(). The class dump will have double lines.
#2
08/03/2005 (10:40 am)
I can confirm this.
#3
08/03/2005 (4:01 pm)
Jinkies, amazed I missed this thread entirely!

Issue #246.
#4
08/04/2005 (9:39 pm)
And fixed. Thanks! I'd be interested in any other fixes/improvements you might have, Dean, too!
#5
08/05/2005 (7:13 am)
Ah good to hear that the code was of use..

As for other fixes: did you get this one?

PS - It's 'Daan' not Dean ;) (pronounced a like 'Dahn' in english)
#6
08/05/2005 (5:07 pm)
Good one, thanks Daan!
#7
10/07/2005 (10:24 pm)
This seems to still be bugged in 1.4 RC2. :(
#8
10/08/2005 (11:52 am)
This seems to fix it... remove these lines:

ConsoleLogger::ConsoleLogger()
{
   mInitalized = false; // REMOVE THIS!
   mFilename = NULL;
   mLogging = false; )
   mAppend = false;
}


ConsoleLogger::ConsoleLogger( const char *fileName, bool append )
{
   mInitalized = false; // REMOVE THIS;
   mLogging = false;

   mLevel = ConsoleLogEntry::Normal;
   mFilename = StringTable->insert( fileName );
   mAppend = append;

   init();
}

... and in addition fix init....

bool ConsoleLogger::init()
{
   if( mInitalized )
      return false; // RETURN TRUE!

   Con::addConsumer( ConsoleLogger::logCallback );
   mInitalized = true;

   return true;
}

Someone else please double check my work here.
#9
10/20/2005 (5:36 pm)
Fixed, and also renamed the var to smInitialized to make things clearer.

And renamed it to smInitialized as well.

Thanks Tom!