10

这是奇怪行为的一天。

我们有一个使用 Delphi 2007 制作的 Win32 项目,它承载 .NET 运行时并调用 .NET 以显示新表单,作为过渡期的一部分。

最近,我们开始在看似随机的位置和代码点遇到异常:算术上溢或下溢。

其中之一的堆栈跟踪如下所示:

at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.RunDialog(Form form)
at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
at System.Windows.Forms.Form.ShowDialog()
at Gatsoft.Gat.UI.Windows.Forms.Remanaging.RemanageForm.DelphiOpenInNewMode(String employeeCode, String departmentCode, DateTime date) in C:\Dev\VS.NET\Gatsoft\Gatsoft.Gat.UI.Windows\Forms\Remanaging\RemanageForm.Delphi.cs:line 67

在 Visual Studio 解决方案中,最外层的类库之一(即,它可以提取所有引用)已经设置了一个特定的调试程序,以 Delphi 项目输出为目标。这允许我们从 Visual Studio 调试 .NET 代码,即使程序的主要部分是用 Delphi 编写的。

该问题仅在从调试器运行时出现,而不是在我们直接运行 exe 文件时(通过资源管理器、快捷方式,甚至是Visual Studio 中的Ctrl+ )。F5

机器上显然没有间谍软件(如 this 暗示的那样

还有什么我们可以检查的吗?


编辑:看起来 .NET 调试器启用了这个 SNaN 标志,而 Delphi 调试器没有。我们将不得不对此进行进一步调查,但现在我将接受@Lorenzo Boccaccia的回答。

显然解决了

好的,看起来我们终于解决了这个问题。对于我们的测试人员来说,在没有附加调试器的情况下开始出现问题,因此我们必须优先考虑问题的优先级。

最后,我们发现了有问题的机器的一个常见问题,它们是配备 NVIDIA Quadro NVS 110M 的 Dell Lattitude D620 笔记本电脑,其系统映像中的旧驱动程序用于配置笔记本电脑,早在 2006 年。

我在网上找到了一篇帖子,虽然我在重新启动以更新显示驱动程序时丢失了 url,导致 .NET 服务崩溃,主要是当机器忙于在屏幕上做某事时。重现他的问题的一种方法是打开 C:\ 的命令提示符并执行 aDIR /S以强制进行大量屏幕更新,这将触发崩溃。

他也有一个 NVIDIA 视频卡。

我的机器上的问题大约每 2-4 次启动我们的程序就会出现,但在更新视频驱动程序后,我已经成功启动了 123 次,没有任何问题。(顺便说一句,我可以为这些事情推荐AutoHotKey )。

所以看起来我们找到了罪魁祸首,一个旧的/有缺陷的 NVIDIA 驱动程序。

更新了这个问题,以便将来有人可以节省一些时间。

现在,如果你能原谅我,我要去角落里哭。

被诅咒了!

我一定是把它搞砸了。在更新视频驱动程序后,我刚刚发布了上述更新,同事的笔记本电脑就出现了故障。

不过,我很肯定它现在是我们应用程序之外的一个问题,所以只需要弄清楚要更新哪些具体的东西。


进一步更新:好的,我的机器现在显然是固定的,我同事的机器不是这样。到目前为止,我们已经更新了 BIOS、芯片组驱动程序,目前 XP 的 SP3 即将推出。

今晚将进行老化测试,该应用程序将在夜间启动,因为问题在启动期间或第一次执行某些 WinForms .NET 代码时突然出现。这个应用程序主要是一个 Delphi Win32 应用程序,但它承载 .NET 运行时,问题似乎与 .NET 代码有关。当我们“启动”.NET 运行时,问题可能会出现,或者当我们从 Win32 触发第一个 .NET 窗口时,它也会出现。


从统计学上讲,我现在准备发布此代码。一夜之间,该应用程序已启动 3051 次而没有出现错误,而在我更新视频驱动程序之前,它每 2-4 次崩溃一次。

发现(!/?)

这种修复错误的折磨感觉就像去看医生,接下来会发生以下对话:

Doc: Does this hurt?
Me: No...
Doc: What about now?

我已经刺激并戳了应用程序,最后我想我已经找到了我们所做的导致这个问题的事情。

在我们的应用程序中,我们托管来自 Delphi 2007 Win32 应用程序的 .NET 运行时,在我们的胶水代码中,我们有以下行(现在):

  rc := CorBindToRuntimeEx('v2.0.50727', 'wks',
  STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN or STARTUP_CONCURRENT_GC,
  @clsid, @iid, UnkRuntimeEngine);

中间的两个常量原来只有一个 0,意思是选择默认值。这种变化是几个月前引入的,此后问题一直在慢慢蔓延到我们身上。引入此更改是为了鼓励 ANTS 分析器加载我们的 Win32 应用程序 + 托管的 .NET 运行时,以便进行性能分析,而我们当时引入的更改使这项工作发挥了作用。此外,算术上溢/下溢的问题正在慢慢变得更糟,所以我敢打赌,这个问题在更改后的一段时间内都没有出现,因此它与我们所做的任何更改都无关。

此外,由于我们仅(最初)在通过调试器运行时看到了问题,因此我们认为 Visual Studio 和/或 Delphi 有问题。

无论如何,现在从统计上看,在一个屏幕上的浏览器重复由 javascript 触发的上下滚动(显然需要触发错误),然后我已经能够成功启动应用程序 726 次,调用中的值为 0 ,并且它在 17 次中有 5 次崩溃,其中有两个常数。

Doc: Does this hurt?

让我们先不要讨论是谁做出了这种改变。我敢肯定罪魁祸首是想匿名...

4

2 回答 2

1

如果在启动应用程序后附加调试器,是否还会出现错误?

于 2008-09-11T18:43:42.687 回答
1

可以使用信号 nan 支持编译链接 dll 的调试版本,有关此问题的示例,请参见http://blogs.msdn.com/oldnewthing/archive/2008/07/02/8679191.aspx 。

heisenbug 是由未初始化的变量引起的,这里可能有一个链接的 dll 启用了 cpu 的 snan 功能并在返回时忘记禁用它

于 2008-09-30T22:26:17.793 回答