正在确定AccessViolationException DragDrop.DoDragDrop的原因

本文关键字:DoDragDrop DragDrop AccessViolationException | 更新日期: 2023-09-27 17:59:09

我有一个WPF应用程序,当启动拖动操作时,它在某些计算机上崩溃,并出现AccessViolationException。

困难在于,它只发生在来自构建服务器的构建中,并且当我在VisualStudio2010中本地构建时从未崩溃。所以我无法遍历代码。

我有以下信息:

  • 我们正在使用.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()

更新:通过反复试验,我能够确定导致此次崩溃的确切代码行,而且它似乎完全有效。作为一个实验,我禁用了包含违规代码行的方法的代码优化,应用程序不再崩溃。

正在确定AccessViolationException DragDrop.DoDragDrop的原因

AV异常是最糟糕的,您应该意识到问题可能源于系统中完全不同的部分。

通常情况下,您会意外访问一个您无法访问的内存位置,程序会照常执行,但稍后另一种方法会尝试访问该内存位置,并通过错误读取错误的数据位置而导致错误。

为了调试,我建议您利用gflags,这是微软提供的一种检测deap损坏的工具。我用了好几次,它为我节省了数小时甚至数天的调试工作。

只是一种预感,但由于您表示正在优化代码,并使用32/64位混合环境:

  1. 验证生成服务器是否为x64位环境
  2. 验证客户端是否具有正确版本的.Net环境
  3. 验证运行该应用程序的客户端是否运行正确的版本,即64位仅由win7 x64系统运行,反之亦然
  4. 确保清除了服务器的临时目录,以前在临时目录中的构建可能会导致类似这样的奇怪问题

还要注意的是,微软的开发人员很愚蠢,他们将两个环境隔离开来,注册表项/程序文件等没有存储在程序指示的地方。这是我在公司创建的一些应用程序中遇到的一个主要障碍。

我也相信剪贴板&拖放调用是STA(单线程apratments)调用。崩溃可能是由于STA和MTA之间的冲突。您有用[STAThread]修饰的Main()函数吗?

我个人认为这篇关于64位迁移的文章很有用:http://www.codeguru.com/cpp/misc/samples/basicprogramming/article.php/c16093/Seven-Steps-of-Migrating-a-Program-to-a-64bit-System.htm

首先检查机器上是否安装了所有更新。

稍后,您可以使用debugdiag创建一个crashdump,并检查firstchance和secondchance异常,以获得有关此问题的更多信息。

问候,

Ian

我要做的第一件事就是更新那些笔记本电脑的视频卡驱动程序。

在MS.Win32.UnsafeNativeMethods.

这通常意味着微软的工程师试图告诉你:"嘿,我们没有写这个,它崩溃了。"