关于内存越界的一个bug

一、问题背景

  某天测试反馈,第一次创建角色后进入游戏,有概率出现主角动画丢失。

二、问题分析过程

  角色动画一直是我在负责,并且最近也确实改过相关内容,于是从动画系统下手开始查。既然是随机出现,那么我的第一判断是可能跟时序有关。于是把动画和模型资源异步加载的相关代码都过了一遍,但并没有发现什么线索。于是加了一些log开始在本地试,将近50次的新建角色没有重现。由于手头有其他工作,直接把log上传让测试帮忙重现了。
  第二天某个测试同学复现。看log发现从玩家数据里面读取出来的角色ID是个诡异的值,此值是从服务器同步过来的。理论上创建角色的ID只在第一次创建角色时保存一次,后续不会更改,基本不太可能出错。于是怀疑是客户端读取这个字段的接口对类型处理不当,导致奇怪的值出现。但过了一遍代码,也没有问题。
  开始将问题转向服务器,打开数据库查看该字段值,发现500多个账号有4个该字段是随机值。于是怀疑是不是有代码掉错了接口或者传错了值,发现根本就没有调用的地方。又开始怀疑是不是内存越界了,写穿到这个字段了。看了看这个字段相邻的两个值,均是正常值。一般的内存越界都是连续的,所以暂且也排除这个可能性。
  那还剩一个可能就是创建角色过程中从表格数据里将这个值赋值到玩家角色数据上时出错了。接下来开始分析读表和赋值过程。我们的表格数据使用的txt,读进内存的时候是为每行数据创建一个buffer,使用连续内存存了所有字段的数据。来看下最关键的一句话。

val = *((int64*)((char*)_buff + pos));

  其中_buff表示的是一行数据的buffer指针,pos是偏移。这里的操作是将接下来的8个字节转换为int64类型并取出值,而实际上_buff只剩下4个字节的数据了(策划将角色ID的字段类型配错了,配成了int32)。这里出错的最根本原因是,在做转换的时候,程序使用了玩家数据对应字段的数据类型(int64),而不是表格对应字段的数据类型(int32)进行类型转换。取出数据随机的原因是策划将角色ID配在了最后一列,额外的4个字节越界了,数值不一定是多少。

三、问题解决

  解决问题有两个方法。一种是策划将配表中的类型改为int64。另一个从根本上解决是改程序中的转换,表格数据应该使用表格里配的类型进行转换,而不是使用玩家数据定义的类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值