できることは、Visual Studio (バージョン 2012 以降) に同梱されているデバッグ エンジンであるConcordを使用することです。優れたマネージ API (および vsix テクノロジを使用して展開可能) を介して非常に拡張可能ですが、完全に文書化されているわけではありません。
Concord には、 IDkmDebugMonitorExceptionNotification インターフェイスを使用してフックできるデバッグ モニターの概念があります。
すばらしいことに、このインターフェイスは、スローされたすべての例外を監視できます。また、検出された例外イベントを「抑制する」こともできます。これはまさに必要なものです。
私が提案するのは、Hello Worldサンプルから始めることです: . ダウンロードして、期待どおりに動作することを確認してください。
今、次のHelloWorld.vsdconfigxml
ように変更するだけです:
<!--TODO: If you copy the sample, ensure to regenerate the GUID in this file -->
<!-- 1. change component level to something higher than 40500 -->
<ManagedComponent
ComponentId="51736b11-9fb4-4b6d-8aca-a10a2b7ae768"
ComponentLevel="40501"
AssemblyName="HelloWorld">
<!-- 2. change class full name to HelloWorld.ExceptionHandler, for example -->
<Class Name="HelloWorld.ExceptionHandler">
<Implements>
<InterfaceGroup>
<NoFilter/>
<!-- 3. change supported interface -->
<Interface Name="IDkmDebugMonitorExceptionNotification"/>
</InterfaceGroup>
</Implements>
</Class>
</ManagedComponent>
次に、ExceptionHandler.cs
クラスを作成して、そこに次のようなものを配置します。
public class ExceptionHandler : IDkmDebugMonitorExceptionNotification
{
private bool _unhandledDetected;
// we're being called!
public void OnDebugMonitorException(DkmExceptionInformation exception, DkmWorkList workList, DkmEventDescriptorS eventDescriptor)
{
if (_unhandledDetected)
{
// this will cause the program to terminate
eventDescriptor.Suppress();
return;
}
if (exception.ProcessingStage.HasFlag(DkmExceptionProcessingStage.Unhandled))
{
_unhandledDetected = true;
}
else if (exception.ProcessingStage.HasFlag(DkmExceptionProcessingStage.Thrown))
{
if (SuppressException(exception))
{
eventDescriptor.Suppress();
}
}
}
// should we suppress a thrown (1st chance) exception?
private bool SuppressException(DkmExceptionInformation exception)
{
// implement any custom logic in here, for example use the exception's name
if (exception.Name == typeof(ArgumentOutOfRangeException).FullName)
{
// for example, use the module (assembly) name
var clrAddress = (DkmClrInstructionAddress)exception.InstructionAddress;
var clrModule = clrAddress.ModuleInstance;
if (clrModule.Name == "TheUglyOne.dll")
return true; // we don't want this one!
}
return false;
}
}
プロジェクトを実行すると、監視されているすべての例外が表示されるはずです (「自分のコードのみ」および/または例外トリガーの設定に関係なく)。見たい。私は確認していませんが、Dkm クラスは大量の .NET メタデータ情報を提供するため、カスタム属性を使用してロジックを構築できると思います。
注: ご覧のとおり、プログラムが正常に終了することを確認するためのトリックがあります。