Crash 惊魂

  本来一直下班都很准时的,但是昨天下午被一个问题拖住了。起因是其它 team 在调我们 team 的 dll 时程序异常,由于最近的一个新 feature 是我实现的,所以同事就找到我头上来了。结果调试了一下跟到了一个从来没看过的地方(我们的代码规模实在是太大了,每个人只了解自己 team 负责的部分的一部分代码而已),出错的代码大意如下:

  1. void foo::bar( ... ..., void *pValue )
  2.  {
  3.    bool bTest = (bool)*((bool *)pValue);
  4.    ... ...
  5.  }

  调我们 dll 的同事传过来的值是 1,而上述代码中 pValue 是个指针,结果必然导致访问违例,程序就 crash 了。该同事说这块代码已经很久没改过了,他们一直是这么调的 pFoo->bar( … …, (void *)TRUE );,看了看 foo::bar() 的实现,pValue 确实是被当作 bool 值来使用的。

  找到我们 team 做这一块的同事,他检查了代码之后大吃一惊,说以前的代码一直都是 bool bTest = (bool)pValue; ,谁会改我们的代码呢?用 CVS 查了一下 log,最后找到了“肇事者”,原来是 Mac team 的一个同事,他们升级到 GCC 4.0 以后编译上面代码不能通过,所以就把代码改成了现在这个会导致程序异常的样子。

  这件事其实并不复杂,可是解决过程有点象是在破案一样:)给我们的启示就是:(1)在一个多人协作的环境中(我们目前有十数个 team,几十个人工作在同一个项目中),改其它 team 代码的时候一定要找到相关同事一起进行。(2)这位改代码的同事的代码通过编译是毫无问题的,但是由于上层调用的方式不是拿 pValue 当指针用的,是直接强转传值的,所以修改后的代码必然会出问题。所以,能通过编译的代码未必就能正常运行,修改代码前一定要弄清楚代码的确切含义。

  下班走出公司大楼以后比平时晚了不少,嗯,今天是周末了,可以好好休息一下了。

Leave a Reply