这是奇怪行为的一天.
我们有一个用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).
有明显的机器上没有间谍软件(以As暗示此).
我们可以查看其他任何东西吗?
编辑:看起来.NET调试器正在启用此SNaN标志,而Delphi调试器则没有.我们将不得不进一步调查,但现在我会接受@Lorenzo Boccaccia的回答.
好吧,看起来我们终于解决了这个问题.在没有连接调试器的情况下,问题就开始发生了,对于我们的测试人员来说,所以我们不得不优先考虑问题.
最后,我们发现了有问题的机器的一个常见问题,它们是带有NVIDIA Quadro NVS 110M的Dell Lattitude D620笔记本电脑,以及用于配置笔记本电脑的系统映像的旧驱动程序,从2006年开始.
我在网上发现了一个帖子,但是当我重新启动以更新显示驱动程序时,我丢失了网址,因为.NET服务崩溃,主要是当机器忙于在屏幕上做某事时.重现他的问题的一种方法是打开命令提示符C:\并执行一个DIR /S
只是强制大量的屏幕更新,这将触发崩溃.
他也有一张NVIDIA显卡.
我的机器上的问题大致发生在我们程序的每2-4个初创公司,但在更新视频驱动程序后,我有123个成功的初创公司没有任何问题.(顺便说一句,我可以为这些东西推荐AutoHotKey).
所以看起来我们已经找到了罪魁祸首,一个老/错误的NVIDIA驱动程序.
更新了这个问题,以便将来有人可以节省一些时间.
现在,如果你原谅我,我会在角落里哭泣.
我一定是把它弄糊涂了.在更新视频驱动程序后,我刚发布上述更新,而不是同事笔记本电脑发生故障.
尽管如此,我很肯定这是我们的应用程序之外的问题,所以它仍然需要确定要更新的具体内容.
进一步的更新:好的,我的机器现在显然是固定的,与我的同事机器不一样.到目前为止,我们已经更新了BIOS,芯片组驱动程序,目前SP3 for XP正在进行中.
今晚将进行老化测试,应用程序将在一夜之间启动,因为问题在启动期间或在第一次执行某些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(显然需要触发错误)触发上下重复滚动,然后我已经能够在呼叫中使用0成功启动应用程序726次并且它在那里用两个常数在17次中崩溃了5次.
Doc: Does this hurt?
让我们不要首先考虑谁做出了这种改变.我确定罪魁祸首想要匿名...... 咳嗽