Dot-Net
Windbg 可以顯示執行緒名稱嗎?
Windbg 應該了解用於將執行緒名稱傳遞給調試器的MS 異常協議。
我不能讓它工作。在網上看有很多例子顯示沒有執行緒名稱的“~”執行緒列表,這就是我所看到的。我正在調試一個 .NET x86 程序,並嘗試了 Windbg 的 WDK 8.1 x86 和 x64 版本。
有誰知道這個功能是否仍然可用?我錯過了什麼?
對於 .NET 執行緒,以下適用於“正常”
Threads(手動創建的執行緒,因為我不知道命名執行緒池執行緒的方法):A
Thread是一個類,因此可以在 .NET 託管堆中找到:0:000>.loadby sos clr 0:000> !dumpheap -stat -type Thread MT Count TotalSize Class Name ... 725e4960 11 572 System.Threading.Thread請注意,還有其他輸出,因為它會
!dumpheap查找類名的一部分。然而,方法表(MT)唯一地標識了一個類,所以這就是我們從現在開始使用的:0:000> !dumpheap -short -mt 725e4960 023123d0 02312464 02313c80 ...這些是
Thread對象的地址。由於它是乾淨的輸出,我們可以在循環中使用它:0:000> .foreach (address {!dumpheap -short -mt 725e4960}) {.echo ${address} } 023123d0 02312464 02313c80 ...在循環內部,我們可以使用地址來獲取有關執行緒的更多資訊。首先,讓我們看看執行緒內部的樣子:
0:000> !do 023123d0 Name: System.Threading.Thread ... Fields: MT Field Offset Type VT Attr Value Name ... 725e3e18 400076e c System.String 0 instance 02313c0c m_Name ...在偏移量
+0xC(取決於位數!),有m_Name成員。那是一個字元串。讓我們看看字元串的樣子:0:000> !do poi(023123d0+c) Name: System.String ... Fields: MT Field Offset Type VT Attr Value Name ... 725e4810 40000ac 8 System.Char 1 instance 4d m_firstChar因此,字元串的第一個字元位於 offset 處
+0x08。.NET 中的字元串是 Unicode,因此我們可以通過以下方式查看它du:0:000> du poi(023123d0+c)+8 02313c14 "My named thread 0"將所有這些知識組合到一個命令中:
.foreach (address {!dumpheap -short -mt 725e4960}) { du poi(${address}+c)+8 }(為便於閱讀而格式化,將其全部放在一行中)
如果您嘗試這樣做,您會發現它可能會輸出類似
00000008 "????????????????????????????????"當
m_Nameis時會發生這種情況null。如果您關心這一點,您可以添加對 null 的檢查:.foreach (address {!dumpheap -short -mt 725e4960}) { .if (poi(${address}+c) != 0) { du poi(${address}+c)+8 } }(為便於閱讀而格式化,將其全部放在一行中)
其他改進:
- 對執行緒 ID 執行相同的操作
- 美化輸出(使用
.printf代替ddanddu)最後結果:
.foreach (address {!dumpheap -short -mt 725e4960}) { .if (poi(${address}+c) != 0) { .printf "%d ",poi(${address}+28); .printf "%mu\r\n", poi(${address}+c)+8 } }