WinDbg では、!locks を呼び出して、現在のプロセスのすべてのクリティカル セクションのリストを取得できます。同じリストを取得するためにデバッグ エンジン API を呼び出す方法があるかどうか疑問に思います。Debug Engine API に基づいて構築された C++ で構築されたカスタム ビルド デバッガーで実行したいと考えています。何かご意見は?
どうもありがとう。
WinDbg では、!locks を呼び出して、現在のプロセスのすべてのクリティカル セクションのリストを取得できます。同じリストを取得するためにデバッグ エンジン API を呼び出す方法があるかどうか疑問に思います。Debug Engine API に基づいて構築された C++ で構築されたカスタム ビルド デバッガーで実行したいと考えています。何かご意見は?
どうもありがとう。
これは比較的簡単で、RTL_CRITICAL_SECTION_DEBUG という構造体を使用する必要があります。プリントアウトに注釈を追加しました。
0:011> dt ntdll!_RTL_CRITICAL_SECTION_DEBUG
+0x000 Type : Uint2B
+0x002 CreatorBackTraceIndex : Uint2B
+0x004 CriticalSection : Ptr32 _RTL_CRITICAL_SECTION // This is pointer to actual critical section
+0x008 ProcessLocksList : _LIST_ENTRY // All critical sections are chained in this doubly linked list
+0x010 EntryCount : Uint4B
+0x014 ContentionCount : Uint4B
+0x018 Flags : Uint4B
+0x01c CreatorBackTraceIndexHigh : Uint2B
+0x01e SpareUSHORT : Uint2B
ご覧のとおり、すべてのクリティカル セクションは同じグローバル リストに属しており、1 つのクリティカル セクションが次のクリティカル セクション (および前のクリティカル セクション) をProcessLocksList
指しています。ProcessLocksList
すべての のアドレスがわかったらProcessLocksList
、RTL_CRITICAL_SECTION 構造体へのポインタを、そこから sizeof(void*) を差し引くことで抽出できます。
ProcessLocksList
最後に、 ntdll!RtlCriticalSectionList によって最初のエントリのアドレスが指定されます。
次のコマンドは、上で述べたことのデモンストレーションです。プロセス内のすべての重要なセクションが出力されます。
!list "-t ntdll!_LIST_ENTRY.Flink -e -x \"ln poi(@$extret-0x4); dt ntdll!_RTL_CRITICAL_SECTION poi(@$extret-0x4)\" ntdll!RtlCriticalSectionList"
必要に応じて x64 用に調整します。
要求に応じて追加: x64 のバージョンは次のとおりです。
!list "-t ntdll!_LIST_ENTRY.Flink -e -x \"ln poi(@$extret-0x8); dt ntdll!_RTL_CRITICAL_SECTION poi(@$extret-0x8)\" ntdll!RtlCriticalSectionList"