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.
Handle SymTagData with inner type of SymTagPointerType.
Increase buffer sizes to avoid buffer overflows.
Avoid infinite loops by logging the children of each type only once.
Avoid too deep nesting by adding a max nesting level.
Print the address for arrays instead of just the name.
Correctly handle the return value of vsnprintf() which returns -1 if the buffer is too small http://msdn.microsoft.com/en-us/library/1kt27hek.aspx . In this case just truncate the output.
This caused a crash on character delete if Logger.entities.player.dump was enabled and set to 3.
Fixes#11539
Log "NULL" for NULL pointers.
Log the correct type instead of <user defined> for pointers and log its fields recursively.
Log locals of all threads.
Log the address if retrieving the value threw an exception.
Increase buffer sizes to avoid buffer overflows.
Fix few issues on WheatyExceptionReport:
- fix NULL dereference exception in GetLogicalAddress() when TC assert in triggered ( *((volatile int*)NULL) = 0; )
- fix infinite loop in DumpTypeIndex() when dumping std types like std::string
- fix FormatSymbolValue() pointing to wrong address when accessing local variable values
- use portable types instead of x86 specific types, this fixes some wrong address issues on x86 platform
- use bigger buffers to format symbols to avoid buffer overflows
Prevents fleeing or feared units from going to upper floor ignoring walls/ceilings with mmaps on(and usually get stucked).
Current implementation just randomly selects a distance and angle against the frighting unit, when in narrow circumstance such as underground caves, such targeting point would be at another floor.
Closes#11300
Ref #9475 (needs fixed confirmation)
Fix a database race condition in authserver that would delay the account ban expiry by 1 login because the query that would have removed the ban was executed asynchronously.
Fix some static analysis issues about uninitialized values. Most of them are false positives, always initialized before being accessed, while some of them are real issues spotted by valgrind too.
Fix some static analysis issues, mostly false positive about fields not initialized in the constructor. It's good practice anyway to always initialize them.
Properly save transport related data to database when saving a Player .
On Player login update the current position as relative to transport, in case the transport moved.
Fix a database race condition between authserver saving session key to database asynchronously and worldserver reading it; session key is now saved synchronously.
- 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"
Add additional assert to assure that helgrind reports related to SQLQueryHolderTask::Execute() and WorldSession::ProcessQueryCallbacks() are false positives.
The only chance for WorldSession::ProcessQueryCallbacks() to access the SQL queries before they are completed is if m_result.ready() is true before the end of SQLQueryHolderTask::Execute() .
Helgrind false positive log:
Possible data race during read of size 8 at 0x2BD641E0 by thread #7
Locks held: none
at : SQLQueryHolder::GetPreparedResult(unsigned long) (QueryHolder.cpp:107)
by : Player::LoadFromDB(unsigned int, SQLQueryHolder*) (Player.cpp:16917)
by : WorldSession::HandlePlayerLogin(LoginQueryHolder*) (CharacterHandler.cpp:807)
by : WorldSession::ProcessQueryCallbacks() (WorldSession.cpp:1112)
by : WorldSession::Update(unsigned int, PacketFilter&) (WorldSession.cpp:401)
by : World::UpdateSessions(unsigned int) (World.cpp:2646)
by : World::Update(unsigned int) (World.cpp:2003)
by : WorldRunnable::run() (WorldRunnable.cpp:60)
by : ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186)
by : ACE_OS_Thread_Adapter::invoke() (in /usr/lib/libACE-6.0.3.so)
by : mythread_wrapper (hg_intercepts.c:233)
by : start_thread (pthread_create.c:311)
This conflicts with a previous write of size 8 by thread #4
Locks held: none
at : SQLQueryHolder::SetPreparedResult(unsigned long, PreparedResultSet*) (QueryHolder.cpp:140)
by : SQLQueryHolderTask::Execute() (QueryHolder.cpp:196)
by : SQLOperation::call() (SQLOperation.h:65)
by : DatabaseWorker::svc() (DatabaseWorker.cpp:45)
by : ACE_Task_Base::svc_run(void*) (in /usr/lib/libACE-6.0.3.so)
by : ACE_Thread_Adapter::invoke_i() (in /usr/lib/libACE-6.0.3.so)
by : ACE_Thread_Adapter::invoke() (in /usr/lib/libACE-6.0.3.so)
by : mythread_wrapper (hg_intercepts.c:233)
Address 0x2BD641E0 is 16 bytes inside a block of size 792 alloc'd
at : operator new(unsigned long) (vg_replace_malloc.c:319)
by : __gnu_cxx::new_allocator<std::pair<SQLElementData, SQLResultSetUnion> >::allocate(unsigned long, void const*) (new_allocator.h:104)
by : std::_Vector_base<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > >::_M_allocate(unsigned long) (in /home/jackpoz/trinity/bin/worldserver)
by : std::vector<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > >::_M_fill_insert(__gnu_cxx::__normal_iterator<std::pair<SQLElementData, SQLResultSetUnion>*, std::vector<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > > >, unsigned long, std::pair<SQLElementData, SQLResultSetUnion> const&) (vector.tcc:483)
by : std::vector<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > >::insert(__gnu_cxx::__normal_iterator<std::pair<SQLElementData, SQLResultSetUnion>*, std::vector<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > > >, unsigned long, std::pair<SQLElementData, SQLResultSetUnion> const&) (stl_vector.h:1024)
by : std::vector<std::pair<SQLElementData, SQLResultSetUnion>, std::allocator<std::pair<SQLElementData, SQLResultSetUnion> > >::resize(unsigned long, std::pair<SQLElementData, SQLResultSetUnion>) (stl_vector.h:707)
by : SQLQueryHolder::SetSize(unsigned long) (QueryHolder.cpp:167)
by : LoginQueryHolder::Initialize() (CharacterHandler.cpp:66)
by : WorldSession::HandlePlayerLoginOpcode(WorldPacket&) (CharacterHandler.cpp:788)
by : WorldSession::Update(unsigned int, PacketFilter&) (WorldSession.cpp:363)
by : World::UpdateSessions(unsigned int) (World.cpp:2646)
by : World::Update(unsigned int) (World.cpp:2003)
- Drop groups (roles than can have inherited roles) and roles (set of
permissions)
- Permissions can now have inherited permissions (those act as roles)
RBAC DB structure is now limited to four tables
- rbac_permissions: Contains permissions and roles
- rbac_linked_permissions: Contains the relation between permissions and
linked permissions (those permissions that have linked permissions are
called roles)
- rbac_default_permissions: Contains the list of permissions to be granted
to each security level [Added to maintain compatibility in an easy way]
- rbac_account_permissions: Contains the list of permissions granted or
denied for a particular account.
NOTE: IF YOU ARE USING CUSTOM PERMISSIONS, ROLES OR GROUPS CHECK THE SQL
BEFORE APPLYING...
Change DatabaseWorkerPool<T>::DirectExecute() to handle PreparedStatement disposal in the same way of DatabaseWorkerPool<T>::Query() , thanks Joschiwald for patch.
Restore 2 disabled warnings, 1 already disabled in CMake with the WITH_WARNINGS flag set to False and the other disabled by default as stated in VS documentation http://msdn.microsoft.com/en-us/library/aa984150.aspx
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)
Change IntervalTimer::Reset() behavior to handle system clock changes forward and backward.
This fixes IntervalTimer:.Passed() returning true till it catches up to the new time, triggering the event up to "std::numeric_limits<time_t>::max() / _interval" times.
Fixes https://github.com/TrinityCore/TrinityCore/issues/5816
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)
Settings within worldserver.conf:
Three settings for secruity level:
0 - None - No change to current system
1 - Email - Always requires the email entered on registration for confirming.
2 - RBAC - Groups applied with the RBAC role always require the email entered on registration for confirming.
RBAC default to every group. Changed some logs to make it more clear what is going on at all.
Emails may now no longer exceed 64 chars. Current email is used as regmail.
On account creation, two emails are saved. Registration email and normal email. Normal email is relevant afterwards. Registration email can be changed by console ONLY.
Includes new commands and changes to existing ones:
.account fulfills several new functions:
* Still prints GM Level.
* If account has permission, it displays the current email. This is not defaulted to any group.
* Security level is displayed. Also displays if user has RBAC perm if RBAC security mode is selected
.account email allows user to change email with sufficient confirmation
.account set sec email allows higher sec with higher sec than account to change the normal email. Registrationemail remains untouched here.
.account set sec regmail allows console to change registration email.
.pinfo now displays the registration and normal mail.
Also fixes .learn all crafts.
Closes#10558