2012-05-18 35 views
3

在WinDbg中,可以調用!locks來獲取當前進程中所有關鍵部分的列表。我想知道是否有一種方法可以調用調試引擎API來檢索相同的列表。我想在一個構建於調試引擎API上的C++構建的定製構建調試器中執行此操作。有什麼想法嗎?如何獲取進程中關鍵部分的列表

非常感謝。

回答

4

這是比較直接的,你需要使用稱爲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 

正如你可以看到,所有的關鍵部分屬於同一個全局列表,其中一個的ProcessLocksList關鍵部分指向到下一個關鍵部分的ProcessLocksList(以及對以前)。一旦知道了所有ProcessLocksList的地址,就可以通過從其中減去sizeof(void *)來提取指向RTL_CRITICAL_SECTION結構的指針。

最後,第一個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" 
+0

非常感謝。這非常有幫助。你能否提供64位版本?另外,有沒有什麼辦法可以在dbghelp.dll和/或dbgeng.dll的幫助下直接檢查C++程序中的_RTL_CRITICAL_SECTION_DEBUG? – awatto

+0

@awatto - x64版本現在被添加到答案 - 這是一個從0x4到0x8的簡單變化,以補償指針類型大小。 –

+0

@awatto - 回答第二個問題 - 在winnt.h中聲明瞭RTL_CRITICAL_SECTION和RTL_CRITICAL_SECTION_DEBUG結構,因此使用應用程序中的結構應該沒有問題。例如,如果您有一個指向關鍵部分實例的指針,則可以指向RTL_CRITICAL_SECTION的指針,然後使用字段DebugInfo作爲指向RTL_CRITICAL_SECTION_DEBUG結構的指針。 –

相關問題