Это день странного поведения.
У нас есть проект Win32, созданный с помощью Delphi 2007, который содержит среду выполнения .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. Это позволяет нам отлаживать .NET-код из Visual Studio, хотя основная часть программы написана в Delphi.
Проблема возникает только при запуске из отладчика, а не только при непосредственном запуске exe файла (либо через проводник, ярлыки, либо даже Ctrl + F5 внутри Visual Studio).
На машине, по-видимому, нет программ-шпионов (как намечено this).
Любые другие вещи, которые мы можем проверить?
Изменить: Похоже, что отладчик .NET включает эти SNaN-флаги, а отладчик Delphi - нет. Нам придется исследовать это дальше, но на данный момент я буду принимать ответ @Lorenzo Boccaccia.
По-видимому, Solved
Хорошо, похоже, что мы наконец прикрепили эту проблему. Проблема возникла без использования отладчика для наших тестеров, поэтому нам пришлось расставить приоритеты проблемы.
Наконец, мы обнаружили одну общую проблему с машинами, у которых была проблема: это ноутбуки Dell Lattitude D620 с NVIDIA Quadro NVS 110M со старым драйвером из образа системы, используемого для предоставления ноутбуков, начиная с 2006 года.
Я нашел одно сообщение в Интернете, хотя я потерял URL-адрес, когда перезагрузил его, чтобы обновить драйвер дисплея, в котором произошла сбой службы .NET, в основном, когда машина была занята чем-то на экране. Один из способов воспроизвести его проблему состоял в том, чтобы открыть командную строку для C:\и сделать DIR /S
, чтобы просто заставить массивное количество обновлений экрана, что приведет к сбою.
У него тоже была видеокарта NVIDIA.
Проблема на моей машине происходила примерно каждые 2-4 стартапа нашей программы, но после обновления видеодрайвера у меня было 123 успешных стартапа без каких-либо проблем. (BTW Я могу порекомендовать AutoHotKey для таких вещей).
Итак, похоже, что мы нашли виновника, старый/багги драйвер NVIDIA.
Обновлен этот вопрос, чтобы кто-то в будущем мог сэкономить некоторое время.
Теперь, если вы извините меня, я буду кричать в углу.
Jinxed!
Я, должно быть, сглазил это. Не успел я опубликовать вышеупомянутое обновление, чем ноутбук коллеги, после обновления видеодрайвера.
Тем не менее, я уверен, что это проблема за пределами нашего приложения, поэтому просто нужно выяснить, какие конкретные вещи нужно обновить.
Дальнейшие обновления: Хорошо, теперь моя машина, по-видимому, исправлена, а не с моей коллегой. До сих пор мы обновили BIOS, драйверы набора микросхем и в настоящее время SP3 для XP находятся на пути.
Тест на прожог будет выполнен сегодня вечером, когда приложение будет запущено в ночное время, поскольку проблема возникла либо во время запуска, либо в первый раз был запущен некоторый код WinForms.NET. Это приложение в основном является приложением Delphi Win32, но оно содержит среду выполнения .NET, и проблема, похоже, связана с кодом .NET. Когда мы "загружаем" среду выполнения .NET, может возникнуть проблема или когда мы запускаем первое .NET-окно из Win32, оно также может появляться.
Статистически я готов выпустить этот код сейчас. Ночью приложение было запущено 3051 раз без ошибок, тогда как до того, как я обновил видеодрайвер, он разбился каждые 2-4 раза.
Произведено и найдено (!/?)
Это испытание на исправление ошибок похоже на посещение врача, где начинается следующий разговор:
Doc: Does this hurt?
Me: No...
Doc: What about now?
Я подтолкнул и подтолкнул приложение, и, наконец, я думаю, что нашел что-то, что мы сделали, и ввел эту проблему.
В нашем приложении мы запускаем среду выполнения .NET из приложения Delphi 2007 Win32, а в нашем клей-коде мы имеем следующую строку (сейчас):
rc := CorBindToRuntimeEx('v2.0.50727', 'wks',
STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN or STARTUP_CONCURRENT_GC,
@clsid, @iid, UnkRuntimeEngine);
Две константы в середине были изначально только 0, что означает выбор значений по умолчанию. Это изменение было введено несколько месяцев назад, и проблема после этого медленно ползла к нам. Это изменение было внесено для того, чтобы стимулировать профилировщик ANTS для загрузки нашего исполняемого файла .NET с .NET +.NET, чтобы выполнить профилирование производительности, и изменения, которые мы ввели, затем сделали эту работу. Кроме того, проблема с арифметическим переполнением/нижним потоком постепенно ухудшалась, поэтому я уверен, что проблема не появилась какое-то время после изменения, поэтому она не была приписана ни одному из изменений, которые мы сделали.
Кроме того, поскольку мы только (изначально) видели проблему при работе с отладчиком, мы думали, что что-то не так с Visual Studio и/или Delphi.
В любом случае, статистически сейчас, когда браузер на одном экране выполняет повторяющуюся прокрутку вверх и вниз, вызванную javascript (по-видимому, для того, чтобы вызвать ошибку), тогда я смог успешно запустить приложение 726 раз с помощью 0 в вызове, и он сбрасывает 5 из 17 раз с двумя константами.
Doc: Does this hurt?
И пусть не попадет в то, кто сделал это изменение в первую очередь. Я уверен, что виновник хочет остаться анонимным... кашель