事情是这样的,项目在同一个系统下运行着2个程序A和B,A由同事负责,B由我负责。 A和B会有共享的一块内存, 内存主要分成几种情况:
- 由A填写, B来读取
- 由B填写, A来读取
- B自己读写
- A自己读写
各部分内存没有机制保证被合法读写, 只能通过代码写入的地址保证。 这种情况下, 应该各自封装接口,对地址越界的情况进行判断,然后通过接口调用,这样才能保证内存的安全访问。
然后,问题是这样的,程序在开启某个功能的时候, B程序肯定就会崩溃。 通过调用栈分析,是由于某个全局指针变量的内容被改写了, 然后程序使用错误的地址访问内存,导致崩溃。通过B程序代码的各种分析,也无法查到任何内存会被改写的情况。和组内另一个资深员工,分析了很多场景都无法搞清楚问题的原因。甚至祭出了回滚代码,二分查找问题的土方法了, 竟然发现很早之前的代码也存在问题,实在是匪夷所思。就这样过了快一周,惭愧还是没有头绪。最后我翻出了系统手册,分析了内存之间的使用关系,才开始怀疑是A程序导致的问题, 回滚A程序的代码,发现问题没有了。通过GDB断点A程序写内容的函数,证实是A程序地址计算错误,往B程序使用内存写入内容导致问题的。就是这么一个缺乏入参判断的接口,导致了这么一个无厘头的问题,还搭上了大概2人周的时间去定位,真的是代价巨大。
为什么会花费这么长时间才会定位出问题呢?
- 刚接触项目,我对系统的内存使用情况不清晰
- 资深老员工对系统的内存机制也不了解? 以往的经验诱导了他使用代码定位问题,没有从根本上分析问题。
为什么会出现这么低级的错误?
- A程序由一个刚毕业的同事负责,对代码要求不高,经验欠缺。自己的功能都没有测试,内容写错地址了都不知道。。。
- A程序代码入库没有四眼检视,但凡有一个稍有经验的人进行代码检视,这种低级问题应该是可以被拦截在此阶段的。
- A程序地址写内容的接口不健壮,缺少基本的入参判断, 历史的锅?
终于,问题是解决了,但是不知道未来还有多少坑。要锻造出健壮的代码,和程序员的编程素质相关,跟公司的开发流程相关。程序员需要对系统机制了解的足够深透,实现的功能需要通过充分的自测才跟他人联调,代码入库一定需要四眼检视。
在以往的公司,这些都是基本的流程,然而,以往终究是以往,自己还是需要保持好这些习惯。遇事要敢于怀疑别人。。。 呵呵~
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。