Это день странного поведения.
У нас есть проект 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 .
Видимо Решено
Хорошо, похоже, мы наконец-то решили эту проблему. Проблема начала возникать без присоединения отладчика для наших тестировщиков, поэтому мы должны были расставить приоритеты для этой проблемы.
Наконец, мы обнаружили одну распространенную проблему с машинами, на которых возникла проблема: это ноутбуки Dell Latitude D620 с NVIDIA Quadro NVS 110M, со старым драйвером из образа системы, который использовался для подготовки ноутбуков, еще в 2006 году.
Я нашел одно сообщение в Интернете, хотя я потерял URL при перезагрузке для обновления драйвера дисплея, в котором произошел сбой службы .NET, в основном, когда машина была занята выполнением каких-либо действий на экране. Один из способов воспроизвести его проблему состоял в том, чтобы открыть командную строку для C: \ и выполнить команду DIR /S
, чтобы просто вызвать огромное количество обновлений экрана, что вызовет сбой.
У него тоже была видеокарта NVIDIA.
Проблема на моей машине возникала примерно каждые 2-4 запуска нашей программы, но после обновления видеодрайвера у меня было 123 успешных запуска без каких-либо проблем. (Кстати, я могу порекомендовать 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 из приложения Win32 для Delphi 2007, и в нашем склеенном коде есть следующая строка (сейчас):
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 в вызове, и он падает 5 из 17 раз с двумя константами там.
Doc: Does this hurt?
И давайте не будем вдаваться в то, кто сделал это изменение в первую очередь. Я уверен, что преступник хочет остаться анонимным ... кашель