确定AccessViolationException DragDrop.DoDragDrop的原因

12
我有一个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()

更新: 经过尝试和错误,我确定了导致这个崩溃的代码行,并且它看起来是完全有效的。作为一个实验,我禁用了包含有问题代码行的方法的代码优化,应用程序不再崩溃。


你尝试过从您的本地系统运行Debug和Release版本之间的差异吗?也许某些#if DEBUG语句会引起不同的行为? - Anton
你正在使用哪个版本的框架? - Edwin de Koning
1
哦,有些事情浮现在脑海中。你的事件处理程序是否偶然序列化了任何东西?如果没有包含在生成序列化器程序集中,则可能会在构建输出时导致问题。或者它是否访问任何文件或其他可能会在未授予足够权限时引起此问题的内容?也许是wow6432节点的注册表访问? - Anton
1
@Sigh 你能展示一下你调用DoDragDrop函数的代码吗? - Davide Piras
我已经寻找这个问题有一段时间了,好问题。 - eran otzap
显示剩余4条评论
4个回答

1

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

通常发生的情况是,您意外访问了一个没有访问权限的内存位置,程序继续按照惯例执行,然而后来另一个方法试图访问该内存位置,并通过错误读取由错误放置的不正确数据而导致错误。

为了调试,我建议您利用gflags,这是Microsoft提供的一种工具,用于检测深度损坏。我使用过它几次,它为我节省了数小时甚至数天的调试工作。


0

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

之后,您可以使用debugdiag创建崩溃转储,并检查firstchance和secondchance异常以获取更多信息。

问候,

Ian


0

我会做的第一件事是更新这些笔记本电脑的显卡驱动程序。

在MS.Win32.UnsafeNativeMethods中...

这通常意味着MS .NET工程师试图告诉你: “嘿,我们没有编写这个程序,它崩溃了。”


0

我有一个直觉,因为您表示正在优化代码,并且使用混合的32/64位环境:

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

还要注意,Microsoft开发人员在分离两个环境以及注册表键/程序文件等方面非常愚蠢。这是我在公司创建一些应用程序时必须克服的主要障碍。

此外,我认为剪贴板和拖放调用是STA(单线程aprartment)调用。崩溃可能来自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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接