天天看點

伺服器部分當機問題

  1. 空指針的使用

    調用了一些内部會銷毀指針的函數(背包函數居多,比如合并物品)後,下面的日志輸出裡面再次用到了該指針

    Tips:普通的空指針判斷起來都很容易,最怕的就是這一些操作指針的接口,在調用時很有必要去接口内部看下是否存在對指針的操作。

  2. 野指針的使用

    家族駐地存在一個自動銷毀的機制。但是之前由于銷毀場景時僅僅銷毀了scene指針,卻沒有銷毀目前scene下的所有Npc。導緻此時那些npc身上存的scene指針都成了野指針,這些npc被人為調用todie銷毀時,通路了其scene這個野指針導緻當機。

    Tips:野指針的問題一般都比較不好直接定位,比較難查。在編碼時需要注意,涉及到一個指針銷毀時,考慮下該指針是否存在一些别的被引用地方,如果有,需要對那些地方做下置nullptr處理;此外盡量不要直接儲存一個指針,比如需要管理npc的話,盡可能儲存期npc的唯一id,而不是指針,再需要通路時,通過唯一id從管理器擷取指針再通路,可以減少這個野指針出現的情況。

  3. 循環的内部釋放了容器

    每日目标功能曾經出過一個bug,玩家開着界面隔天,領取前一日達成的目标時,伺服器當機。基本的原因在于,這個跨天領取時,會周遊更新一個容器的狀态,而周遊過程中調用的一個函數觸發了每日目标的跨天重置機制。這個重置機制會釋放掉目前這個周遊的這個容器,進而導緻了當機。

    Tips:在循環周遊操作一個容器時,其内部的調用接口盡可能避免出現操作容器本身的地方,兩者的邏輯盡可能解耦掉。

  4. 遞歸死循環

    項目裡面有個函數getTopMaster()。是擷取一個npc的最上層主人。這是個循環遞歸擷取的函數,但是由于沒有對遞歸次數做限制,對于一些助戰Npc,策劃通過腳本配置召喚出來,由于配置不當和程式部分代碼不健壯,出現過該函數在無限遞歸循環。

    Tips:所有涉及循環和遞歸的接口,都需要評估下風險,諸如這一類的無法直接預見性循環次數的,都需要人為加一個防錯循環上限值。

  5. 變長消息拷貝溢出

    項目裡曾出現過這樣的情況,Function當機後重新拉起,但是卻引起了Session的當機。排查後發現是Function起來後,Session會同步目前所有的玩家基本資料到Function,當機宕在了這個同步玩家資料的消息拷貝這裡。由于考慮到玩家人數可能會很多,是以在循環拷貝玩家資料到變長消息結構的時候,程式上是做了一個限制的,限制的條件是一次性同步的最大玩家人數。問題就出在這個人數上面,由于玩家的基本資料結構在項目後期是會變大的,導緻之前限定的單次同步人數最大值*一個玩家的基本資料後的總大小大于了我們設定的一次消息發送緩存區的大小,進而導緻了stack-overflow。

    Tips:這個同步政策需要修改為判定目前拷貝進去的這個變長消息的大小是否合法,而不是判定同步的玩家人數。因為導緻棧溢出的是這個消息結構申請的記憶體空間不夠,這個空間大小不僅取決于個數還取決于單個資料結構的目前實際大小。

繼續閱讀