diff --git a/server/gameserver/CMakeLists.txt b/server/gameserver/CMakeLists.txt index e9f0966..1bf75ad 100644 --- a/server/gameserver/CMakeLists.txt +++ b/server/gameserver/CMakeLists.txt @@ -104,7 +104,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") curl hiredis tinyxml2 -# tcmalloc + #tcmalloc + backtrace behaviac_gcc_debug ) else() diff --git a/server/gameserver/app.cc b/server/gameserver/app.cc index 92b3212..d5e1854 100644 --- a/server/gameserver/app.cc +++ b/server/gameserver/app.cc @@ -35,6 +35,8 @@ #include "collider.h" +#include "tracemgr.h" + struct MsgNode { SocketFrom_e sockfrom; @@ -174,6 +176,9 @@ bool App::Init(int argc, char* argv[]) srand(time(nullptr)); InitLog(); +#ifdef DEBUG + TraceMgr::Instance()->Init("gameserver2005"); +#endif PerfMonitor::Instance()->Init(); HandlerMgr::Instance()->Init(); a8::Timer::Instance()->Init(); @@ -235,6 +240,9 @@ void App::UnInit() HandlerMgr::Instance()->UnInit(); PerfMonitor::Instance()->UnInit(); f8::TGLog::Instance()->UnInit(); +#ifdef DEBUG + TraceMgr::Instance()->UnInit(); +#endif UnInitLog(); FreeSocketMsgQueue(); diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 548c8da..e0f5cca 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -35,6 +35,7 @@ #include "team.h" #include "explosion.h" #include "killmgr.h" +#include "tracemgr.h" const int kReviveTimeAdd = 12; const int kSkinNum = 4; @@ -821,6 +822,24 @@ void Human::AddToNewObjects(Entity* entity) void Human::AddToPartObjects(Entity* entity) { +#ifdef DEBUG1 + { + if (!follow_target_) { + for (Human* ob : observers_) { + if (ob->IsPlayer()) { + TraceMgr::Instance()->Trace + (a8::Format("add part_object %d->%d frameno:%d %d", + { + GetUniId(), + ob->GetUniId(), + room->GetFrameNo(), + entity->GetUniId() + })); + } + } + } + } +#endif PartObject part_obj; part_obj.entity_uniid = entity->GetUniId(); part_obj.entity_type = entity->GetEntityType(); @@ -834,11 +853,19 @@ void Human::AddToPartObjects(Entity* entity) void Human::RemovePartObjects(Entity* entity) { #ifdef DEBUG - SendDebugMsg(a8::Format("view_debug frameno:%d remove_part_obj:%d", - { - room->GetFrameNo(), - entity->GetUniId() - })); + if (!follow_target_) { + for (Human* observer : observers_) { + if (observer->IsPlayer()) { + observer->SendDebugMsg(a8::Format("view_debug %d->%d frameno:%d remove_part_obj:%d", + { + GetUniId(), + observer->GetUniId(), + room->GetFrameNo(), + entity->GetUniId() + })); + } + } + } #endif framedata_.part_objects.erase(entity->GetUniId()); entity->OnRemoveFromTargetPartObject(this); @@ -1357,12 +1384,23 @@ void Human::FollowTarget(Human* target) if (target == this) { return; } + int pre_uniid = 0; if (follow_target_) { + pre_uniid = follow_target_->GetUniId(); follow_target_->RemoveObserver(this); } target->AddObserver(this); follow_target_ = target; follow_synced_active_player = false; +#ifdef DEBUG + SendDebugMsg(a8::Format("观战 watch %d->%d->%d frameno:%d", + { + room->GetFrameNo(), + pre_uniid, + follow_target_->GetUniId(), + GetUniId() + })); +#endif } void Human::SendDebugMsg(const std::string& debug_msg) @@ -2404,7 +2442,24 @@ void Human::NotifyObservers(cs::SMUpdate* msg, cs::MFActivePlayerData* active_pl #endif } } +#ifdef DEBUG + observer->SendDebugMsg(a8::Format("观战 notify %d->%d frameno:%d part_obj:%d", + { + GetUniId(), + observer->GetUniId(), + room->GetFrameNo(), + pair.second.entity_uniid + })); +#endif } +#ifdef DEBUG + observer->SendDebugMsg(a8::Format("观战 notify %d->%d frameno:%d", + { + GetUniId(), + observer->GetUniId(), + room->GetFrameNo() + })); +#endif } observer->follow_synced_active_player = true; } else { @@ -3686,7 +3741,6 @@ void Human::DoFollow(int target_id) void Human::OnWatcherDie(Human* watcher) { if (follow_target_ == watcher) { - follow_target_ = nullptr; if (socket_handle != 0 && IsPlayer()) { ((Player*)this)->AsyncRequestWatchWar(true); } diff --git a/server/gameserver/tracemgr.cc b/server/gameserver/tracemgr.cc new file mode 100644 index 0000000..06e3715 --- /dev/null +++ b/server/gameserver/tracemgr.cc @@ -0,0 +1,49 @@ +#include "precompile.h" + +#include "tracemgr.h" + +#ifdef DEBUG + +static void ErrorCallback(void *data, const char *msg, int errnum) +{ + abort(); +} + +static int SimpleCallback(void *data, uintptr_t pc) +{ + return 0; +} + +void TraceMgr::Init(const std::string& filename) +{ + filename_ = filename; + state_ = backtrace_create_state(filename_.c_str(), + 0, + ErrorCallback, + nullptr); + if (!state_) { + abort(); + } + log_file_ = fopen("backtrace.log", "w"); + if (!log_file_) { + abort(); + } +} + +void TraceMgr::UnInit() +{ + if (log_file_) { + fclose(log_file_); + log_file_ = nullptr; + } +} + +void TraceMgr::Trace(const std::string& hint) +{ + fputs(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", log_file_); + fputs(hint.c_str(), log_file_); + backtrace_print(state_, 0, log_file_); + fputs("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", log_file_); +} + +#endif diff --git a/server/gameserver/tracemgr.h b/server/gameserver/tracemgr.h new file mode 100644 index 0000000..a490e53 --- /dev/null +++ b/server/gameserver/tracemgr.h @@ -0,0 +1,27 @@ +#pragma once + +#ifdef DEBUG + +#include + +class TraceMgr : public a8::Singleton +{ + + private: + TraceMgr() {}; + friend class a8::Singleton; + + public: + + void Init(const std::string& filename); + void UnInit(); + + void Trace(const std::string& hint); + + private: + std::string filename_; + backtrace_state* state_ = nullptr; + FILE* log_file_ = nullptr; +}; + +#endif