Windbg should understandMS exception protocol用于将线程名称传递给调试器。Can Windbg可以显示线程名称吗?
我不能得到这个工作。看网上有很多例子显示“〜”线程列表没有线程名称,这就是我看到的。我正在调试一个.NET x86进程,并且我尝试了Windbg的WDK 8.1 x86和x64版本。
有谁知道此功能是否仍然可用?我错过了什么?
Windbg should understandMS exception protocol用于将线程名称传递给调试器。Can Windbg可以显示线程名称吗?
我不能得到这个工作。看网上有很多例子显示“〜”线程列表没有线程名称,这就是我看到的。我正在调试一个.NET x86进程,并且我尝试了Windbg的WDK 8.1 x86和x64版本。
有谁知道此功能是否仍然可用?我错过了什么?
对于.NET线程,为“正常” Thread
秒(手动创建的线程,因为我不知道的方式来命名线程池线程)以下工作:
一个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
因此,该字符串的第一个字符是在偏移+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_Name
是null
。如果你关心的是,你可以添加一个检查空:
.foreach (address {!dumpheap -short -mt 725e4960})
{
.if (poi(${address}+c) != 0) {
du poi(${address}+c)+8
}
}
(格式化的可读性,把它所有在同一行)
其他方面的改进:
.printf
代替dd
和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
}
}
线程池线程与常规线程没有区别,但是为它们命名通常没有意义,因为它们被重用。 –
看来.NET并没有为线程名称使用第一次机会异常协议,尽管我没有时间去验证它。感谢您的教程。我已将您的脚本添加到我很少使用的WinDbg备忘单中! –
我希望我可以多次提出这个答案。 – mark
有谁知道此功能是否仍然可用?
是的,此功能仍然可用。至少对于本机应用程序。
对于.NET应用程序,来自'How to: Set a Thread Name in Managed Code'的方法可能比抛出异常更受欢迎。
你在说什么功能?命名线程或在WinDbg中显示命名线程?请详细说明如何在WinDbg中显示线程名称。 –
我使用WinDbg的自2010年以来,我从来没有见过这样的 –
的职位是从2005年线程的名字,所以你可能会使用WinDbg 6.4.0007.0尝试(找到它在[ Windows 2003 SDK](http://download.cnet.com/Windows-Server-2003-R2-Platform-SDK-ISO-Download/3000-10248_4-10731094.html)) –