Определение причины AccessViolationException DragDrop.DoDragDrop
У меня есть приложение WPF, которое сбой на некоторых компьютерах с AccessViolationException при запуске операции перетаскивания.
Трудность заключается только в сборке с нашего сервера сборки и никогда не сбой при создании локально в Visual Studio 2010. Поэтому я не могу пройти через код.
У меня есть следующая информация:
- Мы используем .net 4.0
- Только сбой при запуске приложения в виде 64-битного процесса, 32-разрядный - это нормально.
- Только сбои для сборки с сервера сборки.
- Не разбивается на каждом компьютере, просто на небольшом подмножестве ноутбуков, который у нас есть. Что, кстати, все та же модель
и аппаратная конфигурация. У всех есть
Windows 7, а некоторые - sp1, некоторые
нет.
Какой следующий шаг я должен предпринять, чтобы диагностировать эту проблему?
Здесь трассировка стека от сбоя, похоже, происходит в неуправляемом коде:
at MS.Win32.UnsafeNativeMethods.DoDragDrop(IDataObject dataObject, IOleDropSource dropSource, Int32 allowedEffects, Int32[] finalEffect)
at System.Windows.OleServicesContext.OleDoDragDrop(IDataObject dataObject, IOleDropSource dropSource, Int32 allowedEffects, Int32[] finalEffect)
at System.Windows.DragDrop.OleDoDragDrop(DependencyObject dragSource, DataObject dataObject, DragDropEffects allowedEffects)
at Acquire.Common.UI.Behaviours.DragDropBehaviour.StartDrag(RoutedEventArgs e)
at Acquire.Common.UI.Behaviours.DragDropBehaviour.AttachedElementMouseMove(Object sender, MouseEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run()
at Acquire.Mica.Application.App.Main()
Update:
Через пробную версию и ошибку я смог определить точную строку кода, вызвавшую этот крах, и он выглядит совершенно корректным. В качестве эксперимента я отключил оптимизацию кода для метода, содержащего строку нарушения кода, и приложение больше не сработает.
Ответы
Ответ 1
Исключение AV являются худшими, вы должны знать, что проблема может возникнуть из совершенно другой части системы.
Что обычно происходит, так это то, что вы случайно попадаете в ячейку памяти, к которой у вас нет доступа, программа продолжает выполняться как обычно, однако позже другой метод пытается получить доступ к этой ячейке памяти и вызывает ошибку, читая неверные данные место там по ошибке.
Чтобы отладить, я предлагаю вам воспользоваться gflags, инструментом, предлагаемым Microsoft для обнаружения сбоев деапа. Я использовал его несколько раз, и это спасло меня, если не дни отладки.
Ответ 2
Просто догадка, но поскольку вы указали, что вы оптимизируете код и используете смешанную среду с 32/64 бит:
- Проверьте сервер сборки на x64-разрядную среду.
- Убедитесь, что у клиентов есть соответствующая версия .Net.
- Убедитесь, что клиенты, на которых запущено приложение, работают с правильной версией, то есть. 64 бит управляется только системами win7 x64 и наоборот.
- Убедитесь, что вы удалили каталоги серверов temp, предыдущие сборки в каталогах temp могут вызвать нечетные проблемы, такие как это.
Также обратите внимание, что разработчики Microsoft идиотские, поскольку они разделяют две среды, а ключи реестра/программные файлы и т.д. не хранятся там, где указывает программа. Это был главный камень преткновения, который мне пришлось преодолеть с помощью некоторых приложений, которые мы создали в моей компании.
Также я считаю, что буфер обмена и перетаскивание + переадресация вызовов - это вызовы STA (Single threaded apratments). Крушение может быть связано с конфликтом между STA и MTA. У вас есть функция Main(), украшенная [STAThread]?
Я лично нашел эту статью в 64-битной миграции полезной: http://www.codeguru.com/cpp/misc/samples/basicprogramming/article.php/c16093/Seven-Steps-of-Migrating-a-Program-to-a-64bit-System.htm
Ответ 3
Прежде всего, проверьте, установлены ли на компьютерах все обновления.
Позже вы можете использовать debugdiag для создания crashdump и проверить исключения firstchance и secondchance, чтобы получить дополнительную информацию по этому вопросу.
Привет,
Ян
Ответ 4
Первое, что я хотел бы сделать, это обновить драйвер видеокарты этих ноутбуков.
в MS.Win32.UnsafeNativeMethods..
Это обычно означает, что MS.NET-инженер пытается сказать вам:
"Эй, мы не писали это, и он разбился".