从内存转储中查找线程消息队列中的消息



我知道一个事实是,在任何给定时间使用任何类型的win api调用,都无法确定线程队列中有多少消息。我的应用程序不起作用,因为有时会发生后说话失败(可能是由于队列增长到10000,尽管我看不出它怎么会这么大)。这是一个断断续续的问题,在发生的那一刻,我有几个内存转储。显然,队列必须在某个地方,本文解释了如何获取http://moyix.blogspot.com/2008_09_01_archive.html

Windows中的每个线程(由_ethread Strucutre表示) 其线程控制块中的字段(或TCB,是_kthread) Win32Thread。该字段指向数据结构,_W32Thread,它 在Windows图形的内核模式部分中定义 子系统,win32k.sys。您实际上可以检查_W32Thread 通过在Windbg中发出" DT Win32K!_W32Thread"来结构;但是,如果你 启动反向工程Win32k.sys,您会很快发现 给出的信息尚未完成。实际上,_w32thread是一个 更大的数据结构,其中包括有关 当前桌面,键盘布局,已安装的窗口钩以及大多数 重要的是,输入消息队列。在Windows XP SP2中, 消息队列在_W32Thread的Offset 0xd0上找到,看起来像:

typedef struct _MSG_QUEUE  {   PMSG_QUEUE_ENTRY Head; 
PMSG_QUEUE_ENTRY Tail;  unsigned long NumberOfMessages;   } MSG_QUEUE;

基本上,我正在尝试找到一个指针msg_queue(这将为我提供数字,而且我可以从头开始枚举它们)。但是,通过分析内存转储,我看上去并不能找到任何_ethread,_kthread和_w32Thread的指针。它们到底存储在哪里,它们是否在过程内存空间中?我必须在内核模式下运行吗?我需要为win32k.sys加载符号吗?我还需要做什么?谢谢。

这不是所有windbg命令的完整答案,但也许仍然有用。

消息队列仅在内核模式下才能访问,因此您需要一个内核转储或使用Sysinternals LiveKD。使用-y开关设置符号路径。

livekd -y srv*d:debugsymbols*http://msdl.microsoft.com/download/symbols

处于内核模式后,找到要调试的过程

!process 0 0 executable.exe

然后获取该过程的线程

!process <process> 4

所有具有Win32Thread不等于0的线程可能很有趣。

Blog文章跳跃队列描述了Windows 7的其余内容。我无法立即遵循,文章实际上并未描述要使用哪种WINDBG命令。我记得在Windows XP上容易得多。

最新更新