--- lang: ja-jp breaks: true --- # C# .NET Framework 4.5.2 AccessViolationException によりアプリが落ちる 2021-05-14 > AccessViolationExceptionを捕捉できるようにする > https://blog.xin9le.net/entry/2015/07/22/053738 ## AccessViolationExceptionを捕捉する ### `[HandleProcessCorruptedStateExceptions]`を、補足したいメソッドの属性に設定するか、App.configに`<legacyCorruptedStateExceptionsPolicy enabled="true" />`を追加する。 ## 以下検証 ### C++側 #### Dll2.cpp ```cpp= // Dll2.cpp : DLL 用にエクスポートされる関数を定義します。 // #include "pch.h" #include "framework.h" #include "Dll2.h" #include <iostream> void Test() { std::cout << "Cの関数 Test() が呼び出されました。" << std::endl; // ここでわざと不正なメモリ参照エラーを出す。 const char *ptr = 0; std::cout << ptr; } void Test_OK() { std::cout << "Cの関数 Test_OK() が呼び出されました。" << std::endl; const char *ptr = "aaaaaaaaaaaaa"; std::cout << ptr; } ``` #### Dll2.h ```cpp= // 以下の ifdef ブロックは、DLL からのエクスポートを容易にするマクロを作成するための // 一般的な方法です。この DLL 内のすべてのファイルは、コマンド ラインで定義された DLL2_EXPORTS // シンボルを使用してコンパイルされます。このシンボルは、この DLL を使用するプロジェクトでは定義できません。 // ソースファイルがこのファイルを含んでいる他のプロジェクトは、 // DLL2_API 関数を DLL からインポートされたと見なすのに対し、この DLL は、このマクロで定義された // シンボルをエクスポートされたと見なします。 #ifdef DLL2_EXPORTS #define DLL2_API __declspec(dllexport) #else #define DLL2_API __declspec(dllimport) #endif extern "C" { __declspec(dllexport) void Test(); __declspec(dllexport) void Test_OK(); } ``` ### C#側 #### Program.cs ```csharp= [DllImport("DLL2.dll")] static extern void Test(); [DllImport("DLL2.dll")] static extern void Test_OK(); //[HandleProcessCorruptedStateExceptions] static void Main(string[] args) { try { Test(); } catch (Exception ex) { if (ex is AccessViolationException) { Console.WriteLine("AccessViolationException!!"); } Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } Test_OK(); Console.WriteLine("処理完了!!"); Console.ReadLine(); } ``` #### App.config ```xml= <?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> </startup> <runtime> <legacyCorruptedStateExceptionsPolicy enabled="true" /> </runtime> </configuration> ``` ### 実行結果  ### `AppDomain.CurrentDomain.UnhandledException`での補足も可能。 `<legacyCorruptedStateExceptionsPolicy enabled="true" />`を設定することで、`UnhandledException`での補足も可能。 ```csharp= AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; ~・・・~ private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { if (e.ExceptionObject is Exception) { Exception ex = e.ExceptionObject as Exception; Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } else { Console.WriteLine(e.ToString()); } } ``` ###### tags: `C#` `.NET Framework 4.5.2` `AccessViolationException`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up