解决了一个ios真机上的内存越界问题

来源:互联网 发布:互联网公司算法 编辑:程序博客网 时间:2024/06/05 09:02

最近在修改一个内存的问题,表面上看是一个野指针的 bug .该 bug 只在设备上出现,win32上无法重现。xcode 的 instrument 根本没法定位问题,win32 上使用了 dr memory ,也没找到根源。最后终于发现了问题, 其实原因说起来也很简单,就是在操作内存时发生了越界。我们项目在读取文件时候,采用读取自己压缩好的数据包的方式,每次读 size 个 char,放到  char[ ] 数组里。 但是却给 char[size]这个位置设置了一个结束符,而该数组操作[ size ] 时发生了越界,导致游戏非常不稳定,出现许许多多莫名其妙的野指针 crash .

这么一说来,原理很简单,错误也很低级,但是从排查到解决用了将近 7 个工作日,并且期间还有另外一个同事也在一起看这个问题。

如果这块代码在 windows上也执行, dr memory 应该是能够检测出来的, 但是因为这块代码在 ios 的宏里面,所以 dr memory 没有查出问题。

xcode 的 instrument 虽然没有用,但是 xcode 可以像下图这样编辑 scheme ,来方便的定位问题。


编辑 scheme 的方法是点 xcode 上方的 product ---> scheme ---> edit scheme

上面图片是从网上别的地方找到的图, xcode 版本额比较老,但是大同小异, 新版本的 xcode 也基本包含这几项。

我们的 crash  bug ,在做了上面的设置之前, 本来非常难以重现, 并且即使重现后,crash 的地方,也指向的是问题表现出来的现象,而不是问题发生的位置。

这样设置之后, crash 的地方基本定位在问题发生的地方,即越界操作了  char[ size ] 这快内存时, 程序就 crash 了。由此可见这样设置之后, xcode  debugger 能够帮助排查这样的非法内存操作行为。

在像上图这样设置后, 因为一个奇怪的原因,在真机上无法调试,但是在 mac的 ios 模拟器上可以调试。我们定位问题,就是在模拟器调试过程中定位到的。

解决了这个问题后,我们的游戏变得非常稳定,一个星期的努力没有白费 ,大家都很开心。

通过解决这个 bug ,我总结了一下几点:

1. 只要是有重现规律的 bug  ,哪怕再复杂,也算是比较容易解决的 bug

2. 了解了 dr memory 的使用,有助于排查 win32 上的内存问题

3. 了解了 xcode scheme 像上图这样设置,能够在  xcode 上排查内存问题

4. 遇到不易重现的问题,没触发一次 crash ,都要认真分析当时的 crash 堆栈。哪怕有些堆栈无法表明真正原因,也要尽可能从当前的情境中了解更多信息。

5. 多读书,多写底层代码,才能从一开始就避免这样的情况发生。





0 0