From 53e1cc8eaad5326215ef4079597f7c987fdaec25 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:07:53 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=BB=E8=BE=91bug=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/game/GameLogic.go | 8 ++++---- src/server/game/log_mgr.go | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/server/game/GameLogic.go b/src/server/game/GameLogic.go index 64b1f6a0..09111df9 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -464,6 +464,7 @@ func G_getGameLogic() *GameLogic { G_GameLogicPtr.M_Players = sync.Map{} G_GameLogicPtr.NotInitPlayer = new(Player) G_GameLogicPtr.M_LimitActiveList = []int{} + G_GameLogicPtr.CreateMessageMgr() // 创建消息管理器 G_GameLogicPtr.OpenTimestampTick() // 开启时间戳计时器 G_GameLogicPtr.RegisterEvent() // 注册事件 G_GameLogicPtr.RegisterNetWorkFunc() // 注册客户端接口 @@ -475,10 +476,9 @@ func G_getGameLogic() *GameLogic { G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器 G_GameLogicPtr.CreateVarMgr() // 创建变量管理器 } - G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器 - G_GameLogicPtr.CreateMailMgr() //创建邮件管理器 - G_GameLogicPtr.CreateMessageMgr() // 创建消息管理器 - ClusterMgrInit() //初始化集群 + G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器 + G_GameLogicPtr.CreateMailMgr() //创建邮件管理器 + ClusterMgrInit() //初始化集群 G_GameLogicPtr.StartTime = time.Now().Unix() // G_GameLogicPtr.CreateHttpManager() } diff --git a/src/server/game/log_mgr.go b/src/server/game/log_mgr.go index e333826d..e30a375b 100644 --- a/src/server/game/log_mgr.go +++ b/src/server/game/log_mgr.go @@ -199,13 +199,25 @@ func (L *LogMgr) InitManager() { func (L *LogMgr) AddLog(logs *Log) { // 复制结构体和 Param map,避免并发修改导致 json.Marshal 时 panic copyLog := *logs + + // 安全地复制 map,使用 defer recover 防止并发迭代时的 panic if logs.Param != nil { - newParam := make(map[string]interface{}, len(logs.Param)) - for k, v := range logs.Param { - newParam[k] = v - } - copyLog.Param = newParam + func() { + defer func() { + if r := recover(); r != nil { + // 发生 panic 时使用空 map + log.Debug("AddLog: concurrent map read/write detected, using empty map") + copyLog.Param = make(map[string]interface{}) + } + }() + newParam := make(map[string]interface{}, len(logs.Param)) + for k, v := range logs.Param { + newParam[k] = v + } + copyLog.Param = newParam + }() } + // 如果已经开始关闭,直接丢弃 L.Lock.Lock() if L.closing { @@ -214,7 +226,7 @@ func (L *LogMgr) AddLog(logs *Log) { } // 非阻塞入队:若通道满则先丢弃最旧一条再入队,避免阻塞调用者 select { - case L.L <- logs: + case L.L <- ©Log: L.Lock.Unlock() return default: @@ -225,7 +237,7 @@ func (L *LogMgr) AddLog(logs *Log) { } // 再尝试入队一次 select { - case L.L <- logs: + case L.L <- ©Log: default: // 放不下就直接丢弃 }