我最近修复了我们产品中的一个缺陷,其症状是访问悬空指针导致的访问冲突。
为了获得良好的实践,我添加了一个单元测试以确保错误不会再次出现。在编写单元测试时,我总是会退出我的缺陷修复并确保单元测试失败,否则我知道它没有正确地完成它的工作。
退出缺陷修复后,我发现我的单元测试仍然通过(不好)。当我将调试器附加到单元测试以查看它为什么通过时,测试失败(即抛出异常)并且我可以中断并观察调用堆栈与我修复的原始缺陷中的调用堆栈匹配。
我没有修改 Visual Studio 2005 中的“异常中断”设置,这确实是导致测试工具终止的关键 Win32 异常(即没有正常的异常处理程序)。
例外的文本是:
Unhandled exception at 0x0040fc59 in _testcase.exe: 0xC0000005:
Access violation reading location 0xcdcdcdcd.
注意:位置并不总是0xcdcdcdcd
(已分配但未写入的 Win32 堆内存)。有时是0x00000000
,有时是另一个地址。
这似乎与传统的 Heisenbug 相反,通过调试器观察问题时问题就会消失。就我而言,通过调试器观察它会使问题出现!
我最初的想法是,这是调试器中的时序差异所暴露的竞争条件。但是,当我将跟踪添加到代码并与调试器分开运行时,我打印出来的数据向我表明,应用程序应该以与在调试器下运行时类似的方式中止。但事实并非如此!
关于可能导致这种情况的任何建议?
更新: 我正在缩小这个问题的原因。有关更多详细信息,请参阅此问题。如果我找到它,将用答案更新这个问题。