【问题标题】:How to approach debugging an AccessViolationException in a .Net application on XP如何在 XP 上的 .Net 应用程序中调试 AccessViolationException
【发布时间】:2015-05-26 18:42:28
【问题描述】:

我有一个在 Windows 8.1 机器上使用为 .Net 4.0 编译的 Visual Studio Express 2008 开发的 .net 应用程序

它在 Windows 8.1 机器上运行良好,但在(非常)旧的单核 XP 机器上它偶尔会抛出 AccessViolationException,我不知道为什么。

在调试模式下在 Visual Studio 中运行,我没有得到任何帮助。

程序非常并行,我正在使用 TPL。

事件日志显示了这一点(这对我来说毫无意义):

Stack:
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
    at System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, 
Int32, Int32)
    at System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
    at System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, 
System.Windows.Forms.ApplicationContext)
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[]) 

我使用的标准 .net 之外的唯一库是 System.data.SQLiteNewtonsoft.JSON

应用程序正在使用 JSON 访问 RPC-Post API。

任何想法我的代码可能导致这种情况?就像我说的那样,它只发生在旧的 XP 机器上,但它可能是我只看到的竞争条件,因为它慢得多。我什至不知道从哪里开始!

【问题讨论】:

  • 请贴一些代码 sn-p 以便人们查看和推荐
  • @hellowahab 我不能。正如我在问题中所说,我不知道是什么代码导致了错误。如果我可以发布代码 sn-p 我可以回答我自己的问题。我需要关于在哪里看的提示。我希望有人可以解码事件日志。
  • 对我来说,您的问题似乎与 XP 上运行的任务并行库有关。
  • 如果我不得不猜测,我会说处理程序中的某些内容没有正确同步并导致访问冲突。请注意,您会得到一个托管异常——即您处于 IL 级别。这很可能不是框架本身的错误。
  • 是的,我就是这个意思。很多时候,这些异常来自尝试从后台线程与 ui 交互。你找过那个吗?

标签: .net multithreading task-parallel-library access-violation dispatch


【解决方案1】:

这里有一些可能有用的答案: C# WebBrowser Control System.AccessViolationException

没有一个被接受,但那是因为 OP 不再在受影响的系统上工作。投票最多的,忽略了 OP 认为无关紧要的,是:

  • 重新注册 jscript.dll 库
  • 用互斥锁包围任何访问 Web 浏览器控件的代码块(这个甚至提到它是为了响应 Windows XP 32 位上的异常)

【讨论】:

  • 感谢那些看起来很有希望的潜在客户。
  • 最后解决了什么问题?
【解决方案2】:

我会稍微讨论一下这个问题,认识到您发布的信息无法得到答案是非常重要的。我只能谈谈您需要做些什么来发现有关此崩溃的更多信息。

最重要的细节是崩溃没有发生在 DispatchMessageW() 方法中。您发布的跟踪顶部有大量堆栈帧,但是您看不到它们。因为它们属于非托管代码,所以 CLR 只记录托管代码的跟踪信息。 DispatchMessage() 是一个主要的 winapi 函数,它在不同的情况下做许多不同的事情,它的主要工作是调用窗口的 窗口过程。这是处理窗口特定消息的代码。

从跟踪中可以清楚地看出,崩溃不是由任何 .NET 代码引起的。正如预期的那样,.NET 非常擅长避免 AccessViolationExceptions。您可以在表单上使用一些可能负责的控件。该列表的顶部是 ActiveX 控件、WebBrowser、外壳对话框(如 OpenFileDialog)。所有以本机代码实现并具有非常薄的 .NET 包装器的控件,以使其可用于 .NET 项目。他们通常表现得非常好。但是,这是一台老机器,谁知道呢,这些机器往往被各种“有用”的软件严重感染,这些软件将自己注入任何进程,并且可能很久没有维护了时间。

您提到“非常平行”,这往往是一个危险信号。没有强信号,crash发生在程序的UI线程上,不是工作线程。但这并不排除它,您可能正在以非法方式对窗口执行某些操作并使其不稳定的工作人员运行代码。导致随后的崩溃。如果您一直忠实地使用调试器,而没有故意抑制 InvalidOperationException 并且不在工作线程上创建任何窗口,那么这不是一个强有力的领先优势。

要找到根本原因,您需要使用非托管调试器,以便准确查看崩溃发生的位置。这往往在不止一种方面是粗糙的,比如当它爆炸时不要靠近机器。在这种情况下,您需要要求用户创建崩溃进程的小型转储。 XP 也让这很痛苦,它不是内置功能,如果您的机器无法启动 XP,您将很难使用 minidump。 SysInternals' ProcDump utility 用来记录一个有用的。

从客户那里收到一个后,您需要在调试器中打开它并检查它以找出崩溃的原因。如果您无法理解现在看到的堆栈跟踪,那将会很困难,请务必向更了解 Windows 内部结构的团队成员寻求帮助。谷歌“如何调试小型转储”以了解更多信息,最小的 MSDN 操作指南页面is here

总而言之,不要指望这里会出现奇迹,这将花费您至少一个月的时间来攀登几条陡峭的学习曲线,并且不能保证成功。这激发了第二种方法,如果您的应用程序在任何现代 Windows 版本上稳定,但不是在一台或两台 XP 机器上稳定,那么可以说,这不再是您的问题。是时候让用户更新他的机器了。祝你好运。

【讨论】:

  • 非常感谢您的回答,它包含许多有用的东西(让您感到羞耻社区 wiki'd 它:值得一些赏金)。我从没想过会得到这个错误本身的答案,我只是需要关于如何考虑解决它的建议。也就是说,我开始相信您的论点,即支持 XP 太难了,而且由于原则上我可以强制升级,这可能会更容易。该应用程序确实有一个 WebBrowser 控件,并且可以在其中显示的一些页面可能/正在运行脚本......
  • 我已经接受了这个答案,因为我认为它对处理这种错误有最一般的建议,但我给了下一个答案,因为这是 CW,下一个answer 解决了我的案例中可能出现的具体错误。
猜你喜欢
  • 1970-01-01
  • 2010-09-12
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
相关资源
最近更新 更多