Dot-Net

Windbg 可以顯示執行緒名稱嗎?

  • November 17, 2015

Windbg 應該了解用於將執行緒名稱傳遞給調試器的MS 異常協議。

我不能讓它工作。在網上看有很多例子顯示沒有執行緒名稱的“~”執行緒列表,這就是我所看到的。我正在調試一個 .NET x86 程序,並嘗試了 Windbg 的 WDK 8.1 x86 和 x64 版本。

有誰知道這個功能是否仍然可用?我錯過了什麼?

對於 .NET 執行緒,以下適用於“正常” Threads(手動創建的執行緒,因為我不知道命名執行緒池執行緒的方法):

AThread是一個類,因此可以在 .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代替ddand du

最後結果:

.foreach (address {!dumpheap -short -mt 725e4960}) 
{
   .if (poi(${address}+c) != 0) 
   {
       .printf "%d ",poi(${address}+28);
       .printf "%mu\r\n", poi(${address}+c)+8
   }
}

引用自:https://stackoverflow.com/questions/31555264