1

我正在編寫這個庫,它通過託管代碼將使用的Media Foundation框架在C++/CLI中實現一些基本的音頻播放器功能。我可以播放音頻,停止,暫停等等。對於任何不熟悉媒體基礎的人員,媒體會話都會發布可處理通知的事件。這是通過使用IMFAsyncCallback對象在會話對象上調用BeginGetEvent來完成的。 IMFAsyncCallback定義了您應該實現以處理事件的方法Invoke(IMFAsyncResult)。當事件發生時,invoke方法由具有可以查詢事件信息的IMFAsyncResult對象的工作線程上的會話對象調用。此結果對象由事件線程創建並擁有。來自非託管代碼的System.AccessViolationException?

在我的Invoke實現中,每當我嘗試使用傳遞的IMFAsyncResult對象進行任何操作(包括調用QueryInterface或其他)時,我都會遇到System.AccessViolationException。我已經實現IMFAsyncCallback的對象是在CRT堆上分配的基本C++類(不是託管的),並且事件發佈在CRT堆上也分配的會話對象擁有的線程上。

  1. 什麼可能導致此異常?

  2. 爲什麼我會從通過普通舊C++實現的代碼中拋出.NET託管異常?這只是當你有混合模式組件時會發生什麼?

回答

6

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

聽起來像你有一個簡單的repro這一點 - 你應該能夠通過在程序運行時附加調試器來調試問題,並允許在發生訪問衝突時捕獲訪問衝突。通常,庫包裝它並將其表面化爲另一種類型,並且該異常的原始網站並不明顯。

要從Visual Studio附加到您的進程,請參閱here。當您附加到流氓流程時,請確保您選擇了調試本機代碼和託管代碼的選項。儘可能確保組件和DLL的符號在Symbol path中可用(如果它們是第三方代碼,有些可能不可用)。

要更改異常配置,以便訪問衝突在源上可調試,請參閱here