In case of dynamic file names don't store the FILE* handle in a shared class variable but keep it only at function scope.
Valgrind log:
at _IO_un_link (genops.c:69)
by fclose@@GLIBC_2.2.5 (iofclose.c:55)
by AppenderFile::CloseFile() (AppenderFile.cpp:94)
by AppenderFile::_write(LogMessage const&) (AppenderFile.cpp:66)
by Appender::write(LogMessage&) (Appender.cpp:102)
by Logger::write(LogMessage&) const (Logger.cpp:63)
by Log::write(LogMessage*) (Log.cpp:279)
by Log::vlog(std::string const&, LogLevel, char const*, __va_list_tag*) (Log.cpp:267)
by Log::outMessage(std::string const&, LogLevel, char const*, ...) (Log.h:129)
Address 0x2a1bd2d0 is 0 bytes inside a block of size 568 free'd
at free (vg_replace_malloc.c:468)
by fclose@@GLIBC_2.2.5 (iofclose.c:85)
by AppenderFile::CloseFile() (AppenderFile.cpp:94)
by AppenderFile::_write(LogMessage const&) (AppenderFile.cpp:66)
by Appender::write(LogMessage&) (Appender.cpp:102)
by Logger::write(LogMessage&) const (Logger.cpp:63)
by Log::write(LogMessage*) (Log.cpp:279)
by Log::vlog(std::string const&, LogLevel, char const*, __va_list_tag*) (Log.cpp:267)
by Log::outMessage(std::string const&, LogLevel, char const*, ...) (Log.h:129)
Ignore "w" flag and always use "a" for log files with dynamic name since the file handle is created at every log line and "w" would delete any other logged line from previous _write() calls.
The best solution would be to overwrite only at first call and append at any other call.
- Changed default loggers and appenders
- '.' determines the relation between loggers ("type.subtype" inherits "type" logger setting if logger "type.subtype" is not defined)
- When core logs a message it search for the correct logger (root is the default one)
ie: a message logged with "type.subtype"
* Core will try to find a logger with name "type.subtype", if its not found then will search for "type", again if its not found it will return the default one "root"
Fix race condition in Log by using atomic operators.
Helgrind log:
Possible data race during read of size 8 at 0x7379D98 by thread #1
Locks held: none
at 0x15AE9C7: AppenderFile::_write(LogMessage const&) (AppenderFile.cpp:59)
by 0x15ADFF8: Appender::write(LogMessage&) (Appender.cpp:106)
by 0x159F14E: Logger::write(LogMessage&) (Logger.cpp:83)
by 0x15A215B: Log::write(LogMessage*) (Log.cpp:290)
by 0x15A200F: Log::vlog(LogFilterType, LogLevel, char const*, __va_list_tag*) (Log.cpp:272)
by 0x15A2682: Log::outInfo(LogFilterType, char const*, ...) (Log.cpp:364)
by 0xF7DA28: Master::Run() (Master.cpp:296)
by 0xF835E8: main (Main.cpp:142)
This conflicts with a previous write of size 8 by thread #10
Locks held: none
at 0x15AE9D7: AppenderFile::_write(LogMessage const&) (AppenderFile.cpp:59)
by 0x15ADFF8: Appender::write(LogMessage&) (Appender.cpp:106)
by 0x159F14E: Logger::write(LogMessage&) (Logger.cpp:83)
by 0x15A215B: Log::write(LogMessage*) (Log.cpp:290)
by 0x15A200F: Log::vlog(LogFilterType, LogLevel, char const*, __va_list_tag*) (Log.cpp:272)
by 0x15A2682: Log::outInfo(LogFilterType, char const*, ...) (Log.cpp:364)
by 0xF7EC1F: FreezeDetectorRunnable::run() (Master.cpp:98)
by 0x15A5B3E: ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186)
Address 0x7379D98 is 88 bytes inside a block of size 96 alloc'd
at 0x4C2C857: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
by 0x15A0FE3: Log::CreateAppenderFromConfig(char const*) (Log.cpp:150)
by 0x15A1AED: Log::ReadAppendersFromConfig() (Log.cpp:244)
by 0x15A31B4: Log::LoadFromConfig() (Log.cpp:469)
by 0x15A053B: Log::Log() (Log.cpp:35)
by 0xF75CD1: ACE_Singleton<Log, ACE_Thread_Mutex>::ACE_Singleton() (Singleton.inl:13)
by 0xF754A4: ACE_Singleton<Log, ACE_Thread_Mutex>::instance() (Singleton.cpp:91)
by 0xF8351A: main (Main.cpp:135)
Replace thread-unsafe localtime() http://www.cplusplus.com/reference/ctime/localtime/ with thread-safe portable ACE_OS::localtime_r() .
Helgrind log:
Possible data race during read of size 4 at 0x6F183C0 by thread #1
Locks held: none
at 0x14E72E3: World::InitDailyQuestResetTime() (World.cpp:2772)
by 0x14E3A01: World::SetInitialWorldSettings() (World.cpp:1790)
by 0x101122A: Master::Run() (Master.cpp:164)
by 0x101740C: main (Main.cpp:142)
This conflicts with a previous write of size 4 by thread #2
Locks held: none
at 0x6C2D3BA: __tzfile_compute (tzfile.c:797)
by 0x6C2D036: __tz_convert (tzset.c:627)
by 0x164146C: LogMessage::getTimeStr(long) (Appender.cpp:23)
by 0x1641550: LogMessage::getTimeStr() (Appender.cpp:31)
by 0x1641722: Appender::write(LogMessage&) (Appender.cpp:80)
by 0x1633FCE: Logger::write(LogMessage&) (Logger.cpp:83)
by 0x16433D8: LogOperation::call() (LogOperation.cpp:29)
by 0x16428A4: LogWorker::svc() (LogWorker.cpp:45)
C4100: 'x' : unreferenced formal parameter
C4310: cast truncates constant value
C4389: '==' : signed/unsigned mismatch
C4668: 'x' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
C4701: potentially uninitialized local variable 'x' used
C4826: Conversion from 'HMODULE' to 'DWORD64' is sign-extended. This may cause unexpected runtime behavior.
C6067: Parameter '3' in call to 'sprintf' must be the address of the string
C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'CloseHandle'