来自非托管代码的System.AccessViolationException?

时间:2010-09-06 14:54:31

标签: .net visual-c++ c++-cli access-violation ms-media-foundation

我正在编写这个库,它通过Media Foundation框架在C ++ / CLI中实现一些基本的音频播放器功能,这些功能将由托管代码使用。我可以播放音频,停止,暂停等等。对于不熟悉Media Foundation的任何人,媒体会话都会发布您可以处理通知的事件。这是通过使用IMFAsyncCallback对象在会话对象上调用BeginGetEvent来完成的。 IMFAsyncCallback定义了应该实现的方法Invoke(IMFAsyncResult)来处理事件。发生事件时,调用方法由工作线程上的会话对象调用,该工作线程具有可以查询事件信息的IMFAsyncResult对象。此结果对象由事件线程创建并拥有。

在我的Invoke实现中,每当我尝试用我传递的IMFAsyncResult对象做任何事情(包括只调用QueryInterface或其他东西)时,我都会得到一个System.AccessViolationException。我实现IMFAsyncCallback的对象是在CRT堆上分配的基本C ++类(未托管),事件发布在也在CRT堆上分配的会话对象拥有的线程上。

  1. 可能导致此异常的原因是什么?

  2. 为什么我从普通旧C ++实现的代码中抛出.NET托管异常?这就是当你有一个混合模式组件时会发生什么?

2 个答案:

答案 0 :(得分:8)

Capture a crash dump,然后将其加载到VS 2010或WinDbg进行分析,所有内容都将被显示。 VS 2010会更容易,但WinDbg可能更有效。

由于使用WinDbg是一个更复杂的选项,我将详细说明(根据您的目标平台选择以下32位或64位版本):

  • 下载并安装Debugging Tools for Windows
  • 配置Microsoft Symbol Server

    的调试符号

    .sympath srv*<SymbolCacheDir>*http://msdl.microsoft.com/download/symbols

  • 将崩溃转储文件加载到WinDbg(文件 - >打开崩溃转储...)

  • 为模块配置调试符号

    .sympath+ <PrivatePdbDir>

  • SOS个扩展名加载到WinDbg

    .loadby sos mscorwks; * fw 2-3.5

    .loadby sos clr; * fw 4

  • 下载,解压缩并加载SOSEX个扩展名到WinDbg

    .load <Sosex32or64Dir>\sosex

  • 让WinDbg进行分析

    !analyze -v

  • 使用SOSEX显示当前线程堆栈(包括托管和非托管帧)

    !mk

这很可能会回答你的问题。

答案 1 :(得分:1)

听起来你有一个简单的重复 - 你应该能够通过在程序运行时附加调试器来调试问题,并在访问冲突发生时捕获它。通常,库包装它并将其表示为另一种类型,并且异常的原始站点不明显。

要从Visual Studio附加到您的流程,请参阅here。当您附加到流氓进程时,请确保选择调试本机代码和托管代码的选项。确保Symbol path中的程序集和DLL的符号尽可能可用(如果它们是第三方代码,则某些符号可能不可用)。

要更改Exception配置以便在源代码中调试访问冲突,请参阅here

相关问题