问题的起因
最近新项目上线了,却总遇到一个有些奇怪的问题,有些玩家反馈他们总会登录不上游戏,需要服务器重启才能解决。初步判断是用户管理器出了问题,导致登录流程发生了错误。经过好几天的添加LOG观察,最后定位到一个用户管理器的一个multimap出了问题。最初大佬们的想法是最近上线的新功能把内存写坏了,但排查了好几天,一直没发现问题。
解决
最后还是决定从用户管理器的代码开始查起,最大的嫌疑对象便是其中的multimap,这个容器采用char*做key,存储用户的名字。联想到最近开放的免费改名功能,我便怀疑到是不是改名导致的bug。经过一些试验,最后确定了就是改名引起的。由于原来前辈做那个改名功能的实现方式会导致用户变量的名字发生改变,内存的内容发生了变化。这也就导致了multimap的key指向的内存内容发生了改变,导致multimap的结构被破坏了。(改变map的key值在C++中是一种未定义行为)最后还是对用户管理器中的名字管理器的add方法与remove方法进行了修改。重新new一块内存给multimap做key,然后在remove方法中进行内存回收。
经过几天的观察,这个解决方法是有效的,成功的解决了这个问题。
感悟
由于这套代码框架也是迭代了好几个项目了,所以一般都不会怀疑是原来的老代码有问题,这也导致我们在一开始排查的时候走了弯路。浪费了好几天时间在排查新功能。这件事情告诉我们,该怀疑的就得怀疑。老代码也可能是有隐患的。