Windbg可以显示线程名吗? [英] Can Windbg display thread names?

查看:302
本文介绍了Windbg可以显示线程名吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Windbg应该了解 MS异常协议用于将线程名称传递给调试器。



我不能让这个工作。看网上有很多例子显示〜线程列表,没有线程名,这就是我所看到的。我正在调试.NET x86进程,我已经尝试了Windbg的WDK 8.1 x86和x64版本。



有人知道这个功能是否仍然可用?我失踪了什么

解决方案

对于.NET线程,以下内容适用于正常线程 s(手动创建的线程,因为我不知道一种方式来命名线程池线程):



A 线程是一个类,因此可以在.NET托管堆中找到:

  0:000> .loadby sos clr 
0:000> !dumpheap -stat -type Thread
MT Count TotalSize类名
...
725e4960 11 572 System.Threading.Thread

请注意,还有其他输出,因为!dumpheap 查找类名称的一部分。然而,方法表(MT)唯一标识一个类,所以我们现在使用的是:

  0:000> !dumpheap -short -mt 725e4960 
023123d0
02312464
02313c80
...

这些是线程对象的地址。由于它是干净的输出,我们可以在循环中使用它:

  0:000> .foreach(地址{!dumpheap -short -mt 725e4960}){.echo $ {address}} 
023123d0
02312464
02313c80
...

在循环中,我们可以使用该地址获取有关线程的更多信息。首先,我们来了解一下线程如何在内部:

  0:000> !do 023123d0 
名称:System.Threading.Thread
...
字段:
MT字段偏移类型VT Attr值名称
...
725e3e18 400076e c System.String 0实例02313c0c m_Name
...

在offset + 0xC (取决于bitness!),有$ code> m_Name 成员。那是一个字符串让我们来看一下字符串的样子:

  0:000> !do poi(023123d0 + c)
名称:System.String
...
字段:
MT字段偏移类型VT Attr值名称
...
725e4810 40000ac 8 System.Char 1实例4d m_firstChar

所以,字符串的第一个字符偏移量 + 0x08 。 .NET中的字符串是Unicode,所以我们可以使用 du 查看它:

  0:000> du poi(023123d0 + c)+8 
02313c14我的命名线程0

组合所有这些知识成为一个命令:

  .foreach(address {!dumpheap -short -mt 725e4960})
{
du poi($ {address} + c)+8
}

(格式化为可读性,将其全部放在一行)



如果您尝试这样做,您会发现它可能会输出如

  00000008????????????????? ? 

m_Name null 。如果你关心这个,你可以添加一个支票null:

  .foreach(address {!dumpheap -short -mt 725e4960 })
{
.if(poi($ {address} + c)!= 0){
du poi($ {address} + c)+8
}
}

(格式化为可读性,将其全部放在一行)



其他改进:




  • 为线程ID执行相同操作

  • prettify输出(使用 .printf 而不是 dd du



最终结果:

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

Windbg should understand the MS exception protocol used to pass thread names to a debugger.

I can't get this to work. Looking on the net there are many examples showing "~" thread lists with no thread names, and that's what I see. I'm debugging a .NET x86 process, and I've tried the WDK 8.1 x86 and x64 versions of Windbg.

Does anyone know if this feature is still available? What am I missing?

解决方案

For .NET threads, the following works for "normal" Threads (manually created threads, since I don't know a way to name threadpool threads):

A Thread is a class and thus can be found in the .NET managed heap:

0:000>.loadby sos clr
0:000> !dumpheap -stat -type Thread
      MT    Count    TotalSize Class Name
...
725e4960       11          572 System.Threading.Thread

Note that there is other output as well, since !dumpheap looks for parts of class names. The Method Table (MT) however, identifies a class uniquely, so that's what we use from now on:

0:000> !dumpheap -short -mt 725e4960
023123d0
02312464
02313c80
...

These are the addresses of Thread objects. Since it is clean output, we can use it in a loop:

0:000> .foreach (address {!dumpheap -short -mt 725e4960}) {.echo ${address} }
023123d0
02312464
02313c80    
...

Inside the loop, we can use the address to get more information about the thread. First, let's find out how a Thread looks like internally:

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
...

At offset +0xC (depending on the bitness!), there's the m_Name member. That's a string. Let's find out how a string looks like:

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

So, the first character of the string is at offset +0x08. Strings in .NET are Unicode, so we can view it with du:

0:000> du poi(023123d0+c)+8
02313c14  "My named thread 0"

Combine all this knowledge into a single command:

.foreach (address {!dumpheap -short -mt 725e4960})
{
    du poi(${address}+c)+8
}

(formatted for readability, put it all in one line)

If you try that, you'll find that it may output something like

00000008  "????????????????????????????????"

This happens when m_Name is null. If you care about that, you can add a check for null:

.foreach (address {!dumpheap -short -mt 725e4960})
{
    .if (poi(${address}+c) != 0) {
        du poi(${address}+c)+8
    }
}

(formatted for readability, put it all in one line)

Other improvements:

  • do the same for the thread ID
  • prettify output (use .printf instead of dd and du)

Final result:

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

这篇关于Windbg可以显示线程名吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆