CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT
CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT は、.NET Framework Version 2.0 で導入されました。 .NET Framework Version 4 では、次の 2 つのシナリオでこの HRESULT が返されます。
スレッドが矛盾した状態の構造にアクセスできるように、ハイジャック中のプロファイラーが、任意の時点でスレッドのレジスタ コンテキストを強制的にリセットしたとき。
プロファイラーが、ガベージ コレクションを発生させる情報提供メソッドを、ガベージ コレクションが禁止されているコールバック メソッドから呼び出そうとしたとき。
以降のセクションでは、これら 2 つのシナリオについて説明します。
ハイジャック中のプロファイラー
(この HRESULT はハイジャックを行っていないプロファイラーでも発生する場合がありますが、このシナリオは主にハイジャック中のプロファイラーで発生する問題です。)
このシナリオでは、スレッドが ICorProfilerInfo メソッドを通じてプロファイラー コードの登録または共通言語ランタイム (CLR: Common Language Runtime) の再登録を行うことができるように、ハイジャック中のプロファイラーがスレッドのレジスタ コンテキストを任意の時点で強制的にリセットします。
プロファイル API が提供する ID の多くは、CLR 内のデータ構造を指しています。 ICorProfilerInfo に対する呼び出しでは、通常、これらのデータ構造から情報が読み込まれ、その情報が返されるにすぎません。 しかし、CLR の実行中に、これらの構造の内容が変更される可能性があり、さらにそのためにロックが使用される可能性もあります。 たとえば、プロファイラーがスレッドをハイジャックしたときに、CLR が既にロックを保有していた (またはロックを取得しようとしていた) とします。 スレッドが CLR を再登録して、さらにロックを取得しようとした場合、または変更途中の構造を参照しようとした場合、これらの構造は矛盾した状態となります。 このような状況では、デッドロックやアクセス違反が発生しやすくなります。
一般に、ハイジャック中でないプロファイラーが有効なパラメーターを指定して ICorProfilerCallback メソッド内のコードを実行し、ICorProfilerInfo メソッドを呼び出した場合、デッドロックやアクセス違反が発生することはありません。 たとえば、ICorProfilerCallback::ClassLoadFinished メソッド内で実行されるプロファイラー コードが、ICorProfilerInfo2::GetClassIDInfo2 メソッドを呼び出してクラスに関する情報を取得しようとしているとします。 このコードは、情報が利用できないことを示す CORPROF_E_DATAINCOMPLETE HRESULT を受け取る可能性はありますが、デッドロックやアクセス違反が発生することはありません。 ICorProfilerInfo へのこのような呼び出しは、ICorProfilerCallback メソッドから行われるため、同期的呼び出しと見なされます。
しかし、ICorProfilerCallback メソッドに含まれないコードを実行するマネージ スレッドが行う呼び出しは、非同期呼び出しと見なされます。 .NET Framework Version 1.x では、非同期呼び出しで発生する可能性のある状態を特定することが困難でした。 このため、呼び出しのデッドロックやクラッシュが発生するほか、無効な応答が返される場合もありました。 .NET Framework Version 2.0 では、この問題を回避するために役立つ簡単なチェックがいくつか導入されました。 .NET Framework 2.0 では、安全でない ICorProfilerInfo 関数を非同期で呼び出すと、CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT によるエラーが発生します。
一般に、非同期の呼び出しは安全ではありません。 ただし、次のメソッドは安全であるため、非同期の呼び出しが個別にサポートされています。
詳細については、CLR プロファイル API ブログのエントリ「Why we have CORPROF_E_UNSUPPORTED_CALL_SEQUENCE (CORPROF_E_UNSUPPORTED_CALL_SEQUENCE が発生する理由)」を参照してください。
ガベージ コレクションの発生
このシナリオは、ガベージ コレクションが禁止されているコールバック メソッド (ICorProfilerCallback メソッドの 1 つなど) 内でプロファイラーが実行される場合です。 プロファイラーが、ガベージ コレクションを発生させる可能性のある情報提供メソッド (ICorProfilerInfo インターフェイスのメソッドなど) を呼び出そうとすると、その情報提供メソッドで CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT によるエラーが発生します。
次の表に、ガベージ コレクションが禁止されているコールバック メソッドと、ガベージ コレクションを発生させる可能性のある情報提供メソッドを示します。 この一覧に記載されたいずれかのコールバック メソッド内で実行されるプロファイラーが、この一覧に記載されたいずれかの情報提供メソッドを呼び出すと、その情報提供メソッドで CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT によるエラーが発生します。
ガベージ コレクションが禁止されているコールバック メソッド |
ガベージ コレクションを発生させる情報提供メソッド |
---|---|
参照
参照
ICorProfilerCallback2 インターフェイス