原来这个utilDebug是托管程序集,它内里又通过pinvoke的方式调用了另一个本地dll里函数,也叫utilDebug,而所有的日志实现都在native dll中。

  这时,我突然想来之前dev的一次关于这个utilDebug的checkin,增加了一个函数,我赶紧去看changelist history,我看到了如下的改动:

1:          [DllImport("utilDebug.dll", CharSet=CharSet.Unicode), SuppressUnmanagedCodeSecurity]
2:          private static extern void DebugLogEx(System.Int32 iCategory, System.String szFilename, System.Int32 iLine, System.String sLog);
3:
4:          private static extern bool IsDebugEnabled();

  加红色下划线部分是新加的部分,直到此时我已经恍然大悟,多麽低级的一个错误啊,IsDebugEnabled的实现显然来自native dll,你想要extern之,那加一个DllImport的attribute吧!

  现在基本可以断点,初的错误是因为这个低级错误而导致的,不信我们看看,这个托管的程序集utiDebug的确能编译通过,但是当你试图通过代码调用它的时候,别说调用了,是定义一个该模块类的变量,不用初始化,都会抛出异常,异常信息告诉我们IsDebugEnabled方法找不到实现。

  于是赶紧修改代码,改动如下:

1:          [DllImport("utilDebug.dll", CharSet=CharSet.Unicode), SuppressUnmanagedCodeSecurity]
2:          private static extern void DebugLogEx(System.Int32 iCategory, System.String szFilename, System.Int32 iLine, System.String sLog);
3:
4:          [DllImport("utilDebug.dll", CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
5:          private static extern bool IsDebugEnabled();

  提交build,现在满心欢喜等新build,然后去开个会先(此时已经是第二天中午),没想到的是,会后回来,被dev告知还是安装出错,近乎同一个错误信息,这不是惊天霹雳,因为至少我们已经修复了一个问题,我们已经再逼近真相,我打开native的c++工程,自习看看问题是不是出在这里(显而易见的推理逻辑),很快,发现,依旧是一个很低级的问题,当然应该算是一个knowledge不足的问题,我发现之前被托管代码调用的函数都会用extern C{}包起来,而新加的函数IsDebugEnabled却没有在这里,我把这一发现告诉了dev,dev有点不解,这很难理解,其实不难,stackoverflow一下,道理在明显不过:

  http://stackoverflow.com/questions/8534917/export-dll-method-from-c-to-c-why-i-need-extern-c

  再次修复新问题,

  终于得到一个可以安装的build,那麽这个地方问题都解决了麽,我表示深深担忧,因为IsDebugEnabled的实现又调用了一个第三方的模块来返回属性值,而我担忧的是:

  这个调用自测过了嘛?

  很明显,这一次dev新加的函数没有任何自测信心满满checkin,而作为QA,我也没有在第一时间发现代码的低级错误,而我们的开发流程似乎也有点问题,只有dev lead做code review,代码checkin出build才进行测试,一开始的测试发现问题又怀疑错了方向,作为QA的我没有在第一时间与dev通力合作,而等了几天之后才加入进去,每一方都有责任,都需要吸取教训,改进!

  但是我依然觉得这其中紧要的问题是这篇文章里提到的一点:

  文章:论程序员应具备的职业素质(http://www.cppblog.com/mzty/archive/2006/09/05/12041.html)

  哪一点呢:是这一点:6:测试习惯

  作为一些商业化正规化的开发而言,专职的测试工程师是不可少的,但是并不是说有了专职的测试工程师程序员可以不进行自测;软件研发作为一项工程而言,一个很重要的特点是问题发现的越早,解决的代价越低,程序员在每段代码,每个子模块完成后进行认真的测试,可以尽量将一些潜在的问题早的发现和解决,这样对整体系统建设的效率和可靠性有了大的保证。

  自测,哪怕是简单的测试都能发现并避免这样低等却无比严重而一旦出现问题却比较难调试的情况。

  你说呢?

  本文转载自:http://www.cnblogs.com/dancewithautomation/archive/2012/09/05/2671620.html